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 / FWCyPart.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  35.3 KB  |  1,044 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWCyPart.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //    Support for FW_OCyberPartExtension. Wraps it so that the developer
  9. //    never needs to deal with SOM. Also implements basic recipes.
  10. //
  11. //========================================================================================
  12.  
  13. #ifndef FWFRAMEW_HPP
  14. #include "FWFrameW.hpp"
  15. #endif
  16.  
  17. #ifndef FWCYPART_H
  18. #include "FWCyPart.h"
  19. #endif
  20.  
  21. #ifndef FWCYSTRM_H
  22. #include "FWCyStrm.h"
  23. #endif
  24.  
  25. #ifndef FWMNUBAR_H
  26. #include "FWMnuBar.h"
  27. #endif
  28.  
  29. #ifndef SLCYUTIL_H
  30. #include "SLCyUtil.h"
  31. #endif
  32.  
  33. #ifndef FWPART_H
  34. #include "FWPart.h"
  35. #endif
  36.  
  37. #ifndef FWFRAME_H
  38. #include "FWFrame.h"
  39. #endif
  40.  
  41. #ifndef FWEXTMGR_H
  42. #include "FWExtMgr.h"
  43. #endif
  44.  
  45. #ifndef FWITERS_H
  46. #include "FWIters.h"
  47. #endif
  48.  
  49. #ifndef FWODTHRD_H
  50. #include "FWODThrd.h"
  51. #endif
  52.  
  53. #ifndef FWSOMENV_H
  54. #include "FWSOMEnv.h"
  55. #endif
  56.  
  57. //
  58. // Cyberdog
  59. //
  60.  
  61. #ifndef __CYBERDOG__
  62. #include <Cyberdog.h>
  63. #endif
  64.  
  65. #ifndef SOM_CyberSession_xh
  66. #include <CyberSession.xh>
  67. #endif
  68.  
  69. #ifndef SOM_CyberProgressBroadcaster_xh
  70. #include <CyberProgressBroadcaster.xh>
  71. #endif
  72.  
  73. #ifndef SOM_CyberOpenerPartExtension_xh
  74. #include <CyberOpenerPartExtension.xh>
  75. #endif
  76.  
  77. #ifndef SOM_CyberNavigatorExtension_xh
  78. #include <CyberNavigatorExtension.xh>
  79. #endif
  80.  
  81. #ifndef SOM_CyberServiceMenu_xh
  82. #include <CyberServiceMenu.xh>
  83. #endif
  84.  
  85. #ifndef SOM_CyberStream_xh
  86. #include <CyberStream.xh>
  87. #endif
  88.  
  89. //-----------------------------------------------------------------------------
  90. // FW_TOrderedCollection Runtime Information
  91. //-----------------------------------------------------------------------------
  92. #pragma mark FW_TOrderedCollection Runtime Information
  93.  
  94. typedef FW_TOrderedCollectionIterator<FW_CThread> FW_CThreadsCollectionIterator;
  95.  
  96. #ifdef FW_USE_TEMPLATE_PRAGMAS
  97. #pragma template_access public
  98. #pragma template FW_TOrderedCollection<FW_CThread>
  99. #pragma template FW_TOrderedCollectionIterator<FW_CThread>
  100. #endif
  101.  
  102. FW_DEFINE_AUTO_TEMPLATE (FW_TOrderedCollection, FW_CThread)
  103. FW_DEFINE_AUTO_TEMPLATE (FW_TOrderedCollectionIterator, FW_CThread)
  104.  
  105. #pragma mark -
  106. //========================================================================================
  107. // Class FW_TObjectSafety
  108. //========================================================================================
  109. #pragma mark Class FW_TObjectSafety
  110.  
  111. /*
  112.     FW_TObjectSafety is a smart pointer object. It's reusable and should be put
  113.     in its own file somewhere.
  114.     
  115.     Semantics:
  116.         FW_TObjectSafety()        Assumes ownership of the object.
  117.         ~FW_TObjectSafety()        Deletes its object.
  118.         Release()                Returns its object; no longer owns it.
  119.         No copy construction permitted. No assignment permitted.        
  120. */
  121.  
  122.  
  123. template <class T>
  124. class FW_TObjectSafety {
  125. public:
  126.                     FW_DECLARE_AUTO (FW_TObjectSafety)
  127.                     FW_TObjectSafety (T* object);
  128.                     ~FW_TObjectSafety ();
  129.     T*                 Release ();
  130. private:
  131.                     FW_TObjectSafety (const FW_TObjectSafety<T>& )    {}
  132.     void             operator= (const FW_TObjectSafety<T>& )            {}
  133. private:
  134.     T*                 fObject;
  135. };
  136.  
  137. //-----------------------------------------------------------------------------
  138. // FW_TObjectSafety Runtime Information
  139. //-----------------------------------------------------------------------------
  140.  
  141. #ifdef FW_BUILD_MAC
  142. #pragma segment FWInternet
  143. #endif
  144.  
  145. //-----------------------------------------------------------------------------
  146. // FW_TObjectSafety<T>::FW_TObjectSafety
  147. //-----------------------------------------------------------------------------
  148.  
  149. template <class T>
  150. FW_TObjectSafety<T>::FW_TObjectSafety (T* object)
  151. :    fObject (object)
  152. {
  153.     FW_END_CONSTRUCTOR
  154. }
  155.  
  156. //-----------------------------------------------------------------------------
  157. // FW_TObjectSafety<T>::~FW_TObjectSafety
  158. //-----------------------------------------------------------------------------
  159.  
  160. template <class T>
  161. FW_TObjectSafety<T>::~FW_TObjectSafety ()
  162. {
  163.     FW_START_DESTRUCTOR
  164.     delete fObject;
  165. }
  166.  
  167. //-----------------------------------------------------------------------------
  168. // FW_TObjectSafety<T>::Release
  169. //-----------------------------------------------------------------------------
  170.  
  171. template <class T>
  172. T* FW_TObjectSafety<T>::Release ()
  173. {
  174.     T* temporary = fObject;
  175.     fObject = 0;
  176.     return temporary;
  177. }
  178.  
  179. //-----------------------------------------------------------------------------
  180. // FW_TObjectSafety Runtime Information
  181. //-----------------------------------------------------------------------------
  182. #pragma mark FW_TObjectSafety Runtime Information
  183.  
  184. #ifdef FW_USE_TEMPLATE_PRAGMAS
  185. #pragma template_access public
  186. #pragma template FW_TObjectSafety<FW_CThread>
  187. #pragma template FW_TObjectSafety<FW_CCyberdogHelper>
  188. #endif
  189.  
  190. FW_DEFINE_AUTO_TEMPLATE (FW_TObjectSafety, FW_CThread)
  191. FW_DEFINE_AUTO_TEMPLATE (FW_TObjectSafety, FW_CCyberdogHelper)
  192.  
  193. #pragma mark -
  194. //========================================================================================
  195. // Callback Prototypes
  196. //========================================================================================
  197. #pragma mark Callback Prototypes
  198.  
  199. /*
  200.     We fill in a struct with pointers to these functions, and pass it to the
  201.     extension. When it calls them, it passes in a pointer to that struct.
  202.     We've subclassed the struct, so we just cast it to a pointer
  203.     to our real C++ classes, and call equivalent virtual methods for
  204.     each function.
  205. */
  206.  
  207. void         FW_CallbackOpenCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*, ODPart*, ParameterSet*);
  208. void         FW_CallbackSetCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*, ParameterSet*);
  209. ODBoolean     FW_CallbackCanShowCyberItem        (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  210. void         FW_CallbackShowCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  211. ODWindow*      FW_CallbackGetCyberItemWindow     (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  212. ODBoolean     FW_CallbackIsCyberItemSelected     (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*);
  213. void         FW_CallbackAcquireSelectedCyberItems (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*, CyberItemList*);
  214. ODBoolean    FW_CallbackIsURLSelected         (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*);
  215. void         FW_CallbackGetSelectedURL         (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*, FW_CString& url);
  216. ODBoolean     FW_CallbackHandleCommand         (Environment*, FW_SCyberPartExtensionCallbacks*, long, long, ODFrame*, somToken);
  217.  
  218. #pragma mark -
  219. //========================================================================================
  220. // SOM Utilities
  221. //========================================================================================
  222. #pragma mark SOM Utilities
  223.  
  224. /*
  225.     Since we have a SOM interface, we have to make sure we don't try to
  226.     throw any C++ exceptions out of here; we need to catch them and convert
  227.     them into SOM exceptions.
  228. */
  229.  
  230. static const char FW_kInvalidException[] = "Unknown Exception!"; 
  231.  
  232. #define FW_SOM_CALLBACK_TRY            \
  233.     FW_TRY                            \
  234.     {
  235.  
  236. #define FW_SOM_CALLBACK_ENDTRY        \
  237.     }                                \
  238.     FW_CATCH_BEGIN                    \
  239.     FW_CATCH_REFERENCE(FW_XException, exception)\
  240.     {                                \
  241.         FW_SetException(ev, exception);\
  242.     }                                \
  243.     FW_CATCH_EVERYTHING()            \
  244.     {                                \
  245.         FW_DEBUG_MESSAGE(FW_kInvalidException);\
  246.         FW_SetEvError(ev, kODErrUndefined);\
  247.     }                                \
  248.     FW_CATCH_END
  249.  
  250. #pragma mark -
  251. //-----------------------------------------------------------------------------
  252. // FW_SupportCyberdogIfPresent
  253. //-----------------------------------------------------------------------------
  254.  
  255. FW_CCyberdogHelper* FW_SupportCyberdogIfPresent (Environment* ev, FW_CPart* part, FW_Boolean cymenus, ODCommandID cybase, FW_Boolean cynav)
  256. {
  257.     if (!FW_CyberdogIsInstalled (ev))
  258.         return kODNULL;
  259.     
  260.     FW_CCyberdogHelper* helper = FW_NEW (FW_CCyberdogHelper, (part));
  261.     FW_TObjectSafety<FW_CCyberdogHelper> helperSafety (helper);
  262.     helper->Initialize (ev, cymenus, cybase, cynav);
  263.     part->AdoptEventHandler (ev, helper);
  264.     helperSafety.Release();
  265.     return helper;
  266. }
  267.  
  268. #pragma mark -
  269. //========================================================================================
  270. // Class FW_CCyberdogHelper
  271. //========================================================================================
  272. #pragma mark Class FW_CCyberdogHelper
  273.  
  274. //-----------------------------------------------------------------------------
  275. // FW_CCyberdogHelper Globals
  276. //-----------------------------------------------------------------------------
  277.  
  278. RoutineDescriptor FW_kCyberAbortTaskUPP = BUILD_ROUTINE_DESCRIPTOR (uppCyberAbortProcInfo, FW_CCyberdogHelper::PrivCyberAbort);
  279.  
  280. //-----------------------------------------------------------------------------
  281. // FW_CCyberdogHelper Runtime Information
  282. //-----------------------------------------------------------------------------
  283. #pragma mark FW_CCyberdogHelper Runtime Information
  284.  
  285. FW_DEFINE_AUTO (FW_CCyberdogHelper)
  286.  
  287. //-----------------------------------------------------------------------------
  288. // FW_CCyberdogHelper::FW_CCyberdogHelper
  289. //-----------------------------------------------------------------------------
  290.  
  291. FW_CCyberdogHelper::FW_CCyberdogHelper (FW_CPart* part)
  292. :    FW_CCyberdogCallbacks (part)
  293. ,    fCyberServiceMenu (kODNULL)
  294. ,    fUseNavigator (false)
  295. ,    fCyberdogMenuHandle (kODNULL)
  296. ,    fLoadCyberItemThreadProcedure (0)
  297. ,    fLoadCyberItemThreadParameters (0)
  298. {
  299.     FW_END_CONSTRUCTOR
  300. }
  301.  
  302. //-----------------------------------------------------------------------------
  303. // FW_CCyberdogHelper::~FW_CCyberdogHelper
  304. //-----------------------------------------------------------------------------
  305.  
  306. FW_CCyberdogHelper::~FW_CCyberdogHelper ()
  307. {
  308.     FW_START_DESTRUCTOR
  309.     
  310.     //
  311.     // Menu Support
  312.     //
  313.     
  314.     if (fCyberdogMenuHandle)
  315.         ::DisposeHandle (fCyberdogMenuHandle);
  316.     delete fCyberServiceMenu;
  317.     
  318.     //
  319.     // Thread Support
  320.     //
  321.     
  322.     FW_CThreadsCollectionIterator threads (&fThreads);
  323.     for (FW_CThread* task = threads.First(); threads.IsNotComplete(); task = threads.Next() )
  324.         delete task;
  325. }
  326.  
  327. //-----------------------------------------------------------------------------
  328. // FW_CCyberdogHelper::Initialize
  329. //-----------------------------------------------------------------------------
  330.  
  331. void FW_CCyberdogHelper::Initialize (Environment* ev, FW_Boolean cymenus, ODCommandID cybase, FW_Boolean cynav)
  332. {
  333.     FW_CCyberdogCallbacks::Initialize (ev);
  334.     
  335.     FW_CPart* part = GetPart();
  336.     
  337.     // Even if we don't want the Cyberdog service menus, we should use the Cyberdog Document
  338.     // menu if we are in the memory draft. We don't need to check; Install... does.
  339.     FW_TAcquiredODRefCntObject<ODMenuBar> menus = part->GetMenuBar(ev)->AcquireODMenuBar(ev);
  340.     fCyberdogMenuHandle = GetCyberSession (ev)->InstallCyberDocumentMenu (ev, part->GetODPart(ev), menus);
  341.     
  342.     // Cyberdog service menus take up lots of space and aren't always desirable.
  343.     if (cymenus) {
  344.         fCyberCommands = cybase;
  345.         fCyberServiceMenu = new CyberServiceMenu;
  346.         fCyberServiceMenu->ICyberServiceMenu (ev, menus, part->GetODPart(ev), cybase);
  347.     }
  348.     
  349.     // Ok, do we want to show up in a navigator part?
  350.     if (cynav)
  351.         fUseNavigator = true;
  352. }
  353.  
  354. /*
  355.     Threads Support
  356. */
  357.  
  358. //-----------------------------------------------------------------------------
  359. // FW_CCyberdogHelper::SetLoadCyberItemThreadProcedure
  360. //-----------------------------------------------------------------------------
  361.  
  362. void 
  363. FW_CCyberdogHelper::SetLoadCyberItemThreadProcedure (FW_ThreadProcedure loadCyberItem, void* parameters)
  364. {
  365.     // See DoSetCyberItem
  366.     fLoadCyberItemThreadProcedure = loadCyberItem;
  367.     fLoadCyberItemThreadParameters = parameters;
  368. }
  369.  
  370. //-----------------------------------------------------------------------------
  371. // FW_CCyberdogHelper::DoSetCyberItem
  372. //-----------------------------------------------------------------------------
  373.  
  374. void FW_CCyberdogHelper::DoSetCyberItem (Environment* ev, CyberItem* newItem, ParameterSet* parameters)
  375. {
  376.     FW_UNUSED (ev);
  377.     FW_UNUSED (newItem);
  378.     FW_UNUSED (parameters);
  379.     
  380.     // Should be customized by Developer
  381.     // Must call inherited (done in extension)
  382.     
  383.     // mlanett 6/21/96 Threads Support
  384.     // Now you can install a callback function and when Cyberdog wants
  385.     // you to load something, the framework will create a thread and run the
  386.     // function. Allows you to do the standard customization of FW_CCyberdogHelper 
  387.     // without having to subclass it or mix it into your part.
  388.     if (fLoadCyberItemThreadProcedure) {
  389.         FW_CThread* task = new FW_CThread (fLoadCyberItemThreadParameters, fLoadCyberItemThreadProcedure);
  390.         FW_TObjectSafety<FW_CThread> taskSafety (task);
  391.         fThreads.AddLast (task);
  392.         taskSafety.Release();
  393.     }
  394.     else
  395.         FW_ASSERT (("FW_CCyberdogHelper::DoSetCyberItem - you should either install a callback or override!", false));
  396. }
  397.     
  398. /*
  399.     CloseCyberDraftWindow & Cyberdog Menus Support
  400. */
  401.  
  402. //-----------------------------------------------------------------------------
  403. // FW_CCyberdogHelper::DoMenu
  404. //-----------------------------------------------------------------------------
  405.  
  406. FW_Handled FW_CCyberdogHelper::DoMenu (Environment* ev, const FW_CMenuEvent& event)
  407. {
  408.     ODBoolean handled = FALSE;
  409.     ODCommandID id = event.GetCommandID(ev);
  410.     
  411.     FW_CPart* part = GetPart();
  412.     ODPart* odpart = part->GetODPart (ev);
  413.     FW_CFrame* probableFrame = part->GetLastActiveFrame(ev); // XXX really really need to get the proper frame!
  414.     
  415.     if (fCyberServiceMenu && (fCyberCommands <= id) && (id < (fCyberCommands+1000)))
  416.         handled = fCyberServiceMenu->DoCommand (ev, event.GetCommandID(ev), probableFrame->GetODFrame(ev));
  417.     
  418.     if (!handled && id == kODCommandClose && probableFrame->IsRoot(ev)) {
  419.     /*    FW_CWindow* window = frame->GetWindow(ev);*/
  420.         /*if (!window->IsFloating())*/ {
  421.             CyberSession* cyberSession = GetExtension (ev)->GetCyberSession (ev);
  422.             handled = cyberSession->CloseCyberDraftWindow (ev, odpart);
  423.         }
  424.     }
  425.     
  426.     return handled ? FW_kHandled : FW_kNotHandled;
  427. }
  428.  
  429. //-----------------------------------------------------------------------------
  430. // FW_CCyberdogHelper::DoAdjustMenus
  431. //-----------------------------------------------------------------------------
  432.  
  433. FW_Handled FW_CCyberdogHelper::DoAdjustMenus (Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
  434. {
  435.     FW_UNUSED (menuBar);
  436.     FW_UNUSED (isRoot);
  437.     
  438.     // Damnit, the frame isn't passed in here. 
  439.     // Hopefully ActiveFrame will be the frame with the menu focus.
  440.     if (hasMenuFocus && fCyberServiceMenu) {
  441.         FW_CPart* part = GetPart();
  442.         FW_CFrame* probableFrame = part->GetLastActiveFrame(ev);
  443.         fCyberServiceMenu->Adjust (ev, probableFrame->GetODFrame(ev));
  444.     }
  445.     
  446.     return FW_kNotHandled;
  447. }
  448.  
  449. /*
  450.     CyberItem Utilities
  451. */
  452.  
  453. //-----------------------------------------------------------------------------
  454. // FW_CCyberdogHelper::GetCyberItem
  455. //-----------------------------------------------------------------------------
  456.  
  457. CyberItem* 
  458. FW_CCyberdogHelper::GetCyberItem (Environment* ev)
  459. {
  460.     return GetExtension (ev)->GetCyberItem (ev);
  461. }
  462.  
  463. //-----------------------------------------------------------------------------
  464. // FW_CCyberdogHelper::GetCyberSession
  465. //-----------------------------------------------------------------------------
  466.  
  467. CyberSession* 
  468. FW_CCyberdogHelper::GetCyberSession (Environment* ev)
  469. {
  470.     // Having a CyberSession is equivalent to having the extension.
  471.     CyberPartExtension* extension = GetExtension(ev);
  472.     return extension?
  473.         extension->GetCyberSession (ev):
  474.         ::GetCyberSession(ev); // XXX CD bug sometimes returns null
  475. }
  476.  
  477. //-----------------------------------------------------------------------------
  478. // FW_CCyberdogHelper::InternalizeCyberItem
  479. //-----------------------------------------------------------------------------
  480.  
  481. CyberItem* 
  482. FW_CCyberdogHelper::InternalizeCyberItem (Environment* ev, FW_OSink* sink, Boolean reload)
  483. {
  484.     // Cyberdog must be installed. If Cyberdog is not loaded, it will be.
  485.     CyberItem* ci = kODNULL;
  486.     
  487.     ci = FW_ReadCyberItem (ev, GetCyberSession (ev), sink);
  488.     if (reload)
  489.         GetExtension (ev)->SetCyberItem (ev, ci, kODNULL);
  490.     
  491.     return ci;
  492. }
  493.  
  494. //-----------------------------------------------------------------------------
  495. // FW_CCyberdogHelper::ExternalizeCurrentCyberItem
  496. //-----------------------------------------------------------------------------
  497.  
  498. void 
  499. FW_CCyberdogHelper::ExternalizeCurrentCyberItem (Environment* ev, FW_OSink* sink)
  500. {
  501.     CyberItem* ci = GetCyberItem (ev);
  502.     if (ci) {
  503.         FW_WriteCyberItem (ev, ci, sink);
  504.     }
  505. }
  506.  
  507. /*
  508.     Navigator support
  509. */
  510.  
  511. //-----------------------------------------------------------------------------
  512. // FW_CCyberdogHelper::HandleOpenCyberItem
  513. //-----------------------------------------------------------------------------
  514.  
  515. void FW_CCyberdogHelper::HandleOpenCyberItem (Environment* ev, CyberItem* item, ODPart* openerPart, ParameterSet* parameters)
  516. {
  517.     // By default call the default ("inherited") OpenCyberItem in CyberPartExtension.
  518.     if (!fUseNavigator) {
  519.         FW_CCyberdogCallbacks::HandleOpenCyberItem (ev, item, openerPart, parameters);
  520.         return;
  521.     }
  522.     
  523.     // OpenCyberItem by default opens a little progress window and then our 
  524.     // part by itself. We want to show up in a browser ("Navigator"); this will
  525.     // require us to replace this method.
  526.     
  527.     GetExtension (ev)->SetCyberItem (ev, item, parameters);
  528.     // The extension will call our DoSetCyberItem and we will...
  529.     // 1) hook up the progress bar
  530.     // 2) start reading the data from the network
  531.     
  532.     // Now then, are we already in a navigator part ("browsing in place") or do
  533.     // we need to create one?
  534.     
  535.     FW_TAcquiredODRefCntObject<ODPart> navigator;
  536.     if (openerPart && openerPart->HasExtension (ev, kCyberNavigatorExtension)) {
  537.         // FW_TAcquiredODRefCntObject does not acquire its objects; it only releases them.
  538.         // Normally acquisition is performed by the accessor function but in this case 
  539.         // openerPart was passed in to us.
  540.         openerPart->Acquire(ev);
  541.         navigator = openerPart;
  542.     }
  543.     else {
  544.         navigator = GetCyberSession(ev)->CreateCyberPart (ev, openerPart, kNavigatorKind, kODNULL);
  545.         if (openerPart && openerPart->HasExtension (ev, kCyberOpenerPartExtension)) {
  546.             FW_TAcquiredODRefCntObject<CyberOpenerPartExtension> cope = (CyberOpenerPartExtension*) openerPart->AcquireExtension (ev, kCyberOpenerPartExtension);
  547.             cope->OpenPart (ev, item, navigator, parameters);
  548.         }
  549.         else
  550.             navigator->Open (ev, kODNULL);
  551.     }
  552.     
  553.     // Finally make sure the navigator displays us (navigators have lots of 
  554.     // parts but only show one at a time in their frames).
  555.     
  556.     if (navigator->HasExtension (ev, kCyberNavigatorExtension)) {
  557.         FW_CPart* part = GetPart();
  558.         FW_TAcquiredODRefCntObject<CyberNavigatorExtension> nave = (CyberNavigatorExtension*) navigator->AcquireExtension (ev, kCyberNavigatorExtension);
  559.         nave->GoToCyberItem (ev, item, part->GetODPart(ev), parameters);
  560.     }
  561. }
  562.  
  563. //-----------------------------------------------------------------------------
  564. // FW_CCyberdogHelper::AcquireContainingNavigator
  565. //-----------------------------------------------------------------------------
  566.  
  567. ODPart* FW_CCyberdogHelper::AcquireContainingNavigator (Environment* ev)
  568. {
  569.     CyberSession* session = GetCyberSession (ev);
  570.     if (!session)
  571.         return kODNULL;
  572.     
  573.     // It's remotely possible to be embedded in multiple navigators, but they
  574.     // would all be the same, so it's not a problem. Just find the first navigator
  575.     // containing a frame.
  576.     
  577.     FW_CPart* part = GetPart();
  578.     FW_CFrame* probableFrame = part->GetLastActiveFrame(ev);
  579.     if (!probableFrame)
  580.         return kODNULL;
  581.     FW_CPresentationFrameIterator fiter (ev, probableFrame->GetPresentation (ev));
  582.     for (FW_CFrame* f = fiter.First(ev); fiter.IsNotComplete(ev); f = fiter.Next(ev)) {
  583.         ODPart* navigator = session->AcquireContainingNavigatorPart (ev, f->GetODFrame(ev));
  584.         if (navigator)
  585.             return navigator;
  586.     }
  587.     
  588.     return kODNULL;
  589. }
  590.  
  591. //-----------------------------------------------------------------------------
  592. // FW_CCyberdogHelper::MakeCyberProgressBroadcaster
  593. //-----------------------------------------------------------------------------
  594.  
  595. CyberProgressBroadcaster* FW_CCyberdogHelper::MakeCyberProgressBroadcaster (Environment* ev, short mode)
  596. {
  597.     CyberProgressBroadcaster* broadcaster = new CyberProgressBroadcaster;
  598.     broadcaster->ICyberProgressBroadcaster (ev, &FW_kCyberAbortTaskUPP, (Ptr)this);
  599.     // kUnmeteredProgress
  600.     broadcaster->SetProgressMode(ev, mode);
  601.     return broadcaster;
  602. }
  603.  
  604. //-----------------------------------------------------------------------------
  605. // FW_CCyberdogHelper::DoCyberAbort
  606. //-----------------------------------------------------------------------------
  607.  
  608. void FW_CCyberdogHelper::DoCyberAbort (Environment* ev, CyberProgressBroadcaster* broadcaster)
  609. {
  610.     FW_UNUSED (ev);
  611.     
  612.     delete broadcaster;
  613. }
  614.  
  615. //-----------------------------------------------------------------------------
  616. // FW_CCyberdogHelper::PrivCyberAbort
  617. //-----------------------------------------------------------------------------
  618.  
  619. void FW_CCyberdogHelper::PrivCyberAbort (CDAbortProcMessage message, CyberProgressBroadcaster* broadcaster, Ptr selfPtr)
  620. {
  621.     FW_SOMEnvironment ev;
  622.     FW_CCyberdogHelper* self = (FW_CCyberdogHelper*) selfPtr;
  623.     
  624.     switch (message) {
  625.         case kAbortMessage:
  626.             self->DoCyberAbort (ev, broadcaster);
  627.             break;
  628.         default:
  629.             break;
  630.     }
  631. }
  632.  
  633. #pragma mark -
  634. //========================================================================================
  635. // Class FW_CCyberdogCallbacks
  636. //========================================================================================
  637. #pragma mark Class FW_CCyberdogCallbacks
  638.  
  639. //-----------------------------------------------------------------------------
  640. // FW_CCyberdogCallbacks Globals
  641. //-----------------------------------------------------------------------------
  642.  
  643. FW_DEFINE_AUTO (FW_CCyberdogCallbacks)
  644.  
  645. //-----------------------------------------------------------------------------
  646. // FW_CCyberdogCallbacks::FW_CCyberdogCallbacks
  647. //-----------------------------------------------------------------------------
  648.  
  649. FW_CCyberdogCallbacks::FW_CCyberdogCallbacks (FW_CPart* part)
  650. :    fPart (part)
  651. ,    fExtension (0)
  652. {
  653.     openCyberItem =         &FW_CallbackOpenCyberItem;
  654.     setCyberItem =             &FW_CallbackSetCyberItem;
  655.     canShowCyberItem =         &FW_CallbackCanShowCyberItem;
  656.     showCyberItem =         &FW_CallbackShowCyberItem;
  657.     getCyberItemWindow =     &FW_CallbackGetCyberItemWindow;
  658.     isCyberItemSelected =     &FW_CallbackIsCyberItemSelected;
  659.     acquireSelectedCyberItems = &FW_CallbackAcquireSelectedCyberItems;
  660.     isURLSelected =         &FW_CallbackIsURLSelected;
  661.     getSelectedURL =         &FW_CallbackGetSelectedURL;
  662.     handleCommand =         &FW_CallbackHandleCommand;
  663.     
  664.     FW_END_CONSTRUCTOR
  665. }
  666.  
  667. //-----------------------------------------------------------------------------
  668. // FW_CCyberdogCallbacks::~FW_CCyberdogCallbacks
  669. //-----------------------------------------------------------------------------
  670.  
  671. FW_CCyberdogCallbacks::~FW_CCyberdogCallbacks ()
  672. {
  673.     FW_START_DESTRUCTOR
  674. }
  675.  
  676. //-----------------------------------------------------------------------------
  677. // FW_CCyberdogCallbacks::Initialize
  678. //-----------------------------------------------------------------------------
  679.  
  680. void FW_CCyberdogCallbacks::Initialize (Environment* ev)
  681. {
  682.     // Register our extension
  683.     FW_CExtensionManager* manager = fPart->GetExtensionManager(ev);
  684.     FW_ASSERT (manager);
  685.     manager->RegisterExtension (ev, kCyberPartExtension, &CreateCyberExtension, this, FALSE);
  686. }
  687.  
  688. //-----------------------------------------------------------------------------
  689. // FW_CCyberdogCallbacks::GetExtension
  690. //-----------------------------------------------------------------------------
  691.  
  692. CyberPartExtension* FW_CCyberdogCallbacks::GetExtension (Environment* ev)
  693. {
  694.     // Possibilities:
  695.     // (a) We don't have Cyberdog installed. In that case this object should 
  696.     // not be created in the first place: if (FW_HasCyberdog()) { // create
  697.     // (b) Have Cyberdog but we don't want its menus or navigator and it
  698.     // hasn't invoked us (i.e. we are a normal part).
  699.     // (c) Have Cyberdog and have its menus or other such.
  700.      
  701.     // We don't want to load Cyberdog if it's not necessary. Cyberdog will be loaded if:
  702.     // (a) We use Cyberdog menus or the navigator
  703.     // (b) We call GetExtension()
  704.     // (c) Cyberdog calls us.
  705.     
  706.     // To avoid loading Cyberdog (if it's not loaded and you don't NEED it), 
  707.     // call CyberdogIsLoaded.
  708.     
  709.     FW_Boolean create = true;
  710.     FW_CAcquiredODFCyberPartExtension extension = (ODF_FW_OCyberPartExtension*) fPart->GetExtensionManager(ev)->AcquireExtension (ev, kCyberPartExtension, create);
  711.     return extension;
  712. }
  713.  
  714. //-----------------------------------------------------------------------------
  715. // FW_CCyberdogCallbacks::CyberdogIsLoaded
  716. //-----------------------------------------------------------------------------
  717.  
  718. FW_Boolean FW_CCyberdogCallbacks::CyberdogIsLoaded (Environment* ev)
  719. {
  720.     FW_Boolean create = false;
  721.     FW_CAcquiredODFCyberPartExtension extension = (ODF_FW_OCyberPartExtension*) fPart->GetExtensionManager(ev)->AcquireExtension (ev, kCyberPartExtension, create);
  722.     return extension != kODNULL;
  723. }
  724.  
  725. /*
  726.     Cyberdog Callbacks
  727. */
  728.  
  729. //-----------------------------------------------------------------------------
  730. // FW_CCyberdogCallbacks::HandleOpenCyberItem
  731. //-----------------------------------------------------------------------------
  732.  
  733. void FW_CCyberdogCallbacks::HandleOpenCyberItem (Environment* ev, CyberItem* item, ODPart* openerPart, ParameterSet* parameters)
  734. {
  735.     // By default call the default ("inherited") OpenCyberItem in CyberPartExtension.
  736.     fExtension->DefaultOpenCyberItem (ev, item, openerPart, parameters);
  737. }
  738.  
  739. //-----------------------------------------------------------------------------
  740. // FW_CCyberdogCallbacks::DoSetCyberItem
  741. //-----------------------------------------------------------------------------
  742.  
  743. void FW_CCyberdogCallbacks::DoSetCyberItem (Environment* ev, CyberItem* newItem, ParameterSet* parameters)
  744. {
  745.     FW_UNUSED (ev);
  746.     FW_UNUSED (newItem);
  747.     FW_UNUSED (parameters);
  748.     
  749.     // Should be customized by Developer
  750.     // Must call inherited (done in extension)
  751. }
  752.     
  753. //-----------------------------------------------------------------------------
  754. // FW_CCyberdogCallbacks::DoCanShowCyberItem
  755. //-----------------------------------------------------------------------------
  756.  
  757. ODBoolean FW_CCyberdogCallbacks::DoCanShowCyberItem (Environment* ev, CyberItem* item)
  758. {
  759.     FW_UNUSED (ev);
  760.     FW_UNUSED (item);
  761.     
  762.     // This is a test for equality (not identity). If you are showing
  763.     // some variant of the given item, return true. For example,
  764.     // http://Where/ is similar to http://Where/index.html
  765.     // Also, http://Here#Bookmark is similar to http://Here
  766.     // You don't need to test for identity; it's been handled already.
  767.     
  768.     return FALSE;
  769. }
  770.  
  771. //-----------------------------------------------------------------------------
  772. // FW_CCyberdogCallbacks::DoShowCyberItem
  773. //-----------------------------------------------------------------------------
  774.  
  775. void FW_CCyberdogCallbacks::DoShowCyberItem (Environment* ev, CyberItem* item)
  776. {
  777.     FW_UNUSED (ev);
  778.     FW_UNUSED (item);
  779. }
  780.  
  781. //-----------------------------------------------------------------------------
  782. // FW_CCyberdogCallbacks::DoGetCyberItemWindow
  783. //-----------------------------------------------------------------------------
  784.  
  785. ODWindow* FW_CCyberdogCallbacks::DoGetCyberItemWindow (Environment* ev, CyberItem* item)
  786. {
  787.     FW_UNUSED (item);
  788.     
  789.     // I think this API is a Cyberdog bug: it is not acquiring the window!
  790.     // This is not properly thread-safe.
  791.     
  792.     FW_CFrame* probableFrame = fPart->GetLastActiveFrame (ev);
  793.     if (probableFrame) {
  794.         FW_TAcquiredODRefCntObject<ODWindow> theWindow = probableFrame->AcquireODWindow (ev);
  795.         return theWindow;
  796.     }
  797.     
  798.     return kODNULL;
  799. }
  800.  
  801. //-----------------------------------------------------------------------------
  802. // FW_CCyberdogCallbacks::DoIsCyberItemSelected
  803. //-----------------------------------------------------------------------------
  804.  
  805. ODBoolean FW_CCyberdogCallbacks::DoIsCyberItemSelected (Environment* ev, ODFrame* frame)
  806. {
  807.     FW_UNUSED (ev);
  808.     FW_UNUSED (frame);
  809.     
  810.     return FALSE;
  811. }
  812.  
  813. //-----------------------------------------------------------------------------
  814. // FW_CCyberdogCallbacks::DoAcquireSelectedCyberItems
  815. //-----------------------------------------------------------------------------
  816.  
  817. void FW_CCyberdogCallbacks::DoAcquireSelectedCyberItems (Environment* ev, ODFrame* frame, CyberItemList* items)
  818. {
  819.     FW_UNUSED (ev);
  820.     FW_UNUSED (frame);
  821.     FW_UNUSED (items);
  822. }
  823.  
  824. //-----------------------------------------------------------------------------
  825. // FW_CCyberdogCallbacks::DoIsURLSelected
  826. //-----------------------------------------------------------------------------
  827.  
  828. ODBoolean FW_CCyberdogCallbacks::DoIsURLSelected (Environment* ev, ODFrame* frame)
  829. {
  830.     FW_UNUSED (ev);
  831.     FW_UNUSED (frame);
  832.     
  833.     return FALSE;
  834. }
  835.  
  836. //-----------------------------------------------------------------------------
  837. // FW_CCyberdogCallbacks::DoGetSelectedURL
  838. //-----------------------------------------------------------------------------
  839.  
  840. void FW_CCyberdogCallbacks::DoGetSelectedURL (Environment* ev, ODFrame* frame, FW_CString & url)
  841. {
  842.     FW_UNUSED (ev);
  843.     FW_UNUSED (frame);
  844.     
  845.     url = "";
  846. }
  847.  
  848. //-----------------------------------------------------------------------------
  849. // FW_CCyberdogCallbacks::HandleCyberCommand
  850. //-----------------------------------------------------------------------------
  851.  
  852. ODBoolean FW_CCyberdogCallbacks::HandleCyberCommand (Environment* ev, long commandSuite, long command, ODFrame* frame, somToken parameters)
  853. {
  854.     // By default call the default ("inherited") HandleCommand in CyberPartExtension.
  855.     return fExtension->DefaultHandleCommand (ev, commandSuite, command, frame, parameters);
  856. }
  857.  
  858. //-----------------------------------------------------------------------------
  859. // FW_CCyberdogCallbacks::CreateCyberExtension
  860. //-----------------------------------------------------------------------------
  861.  
  862. ODExtension* FW_CCyberdogCallbacks::CreateCyberExtension (Environment* ev, FW_CPart* part, const char* name, void* selfCallbacks)
  863. {
  864.     FW_UNUSED (name);
  865.     
  866.     FW_CCyberdogCallbacks* self = (FW_CCyberdogCallbacks*) selfCallbacks;
  867.     
  868.     ODPart* odpart = part->GetODPart(ev);
  869.     ODF_FW_OCyberPartExtension* cyberPartExtension = new ODF_FW_OCyberPartExtension;
  870.     cyberPartExtension->ICyberPartExtension (ev, odpart);
  871.     cyberPartExtension->SetCallbacks (ev, self);
  872.     
  873.     // This is a bit odd. Basically a Cyberdog part has to be a client of its own extension,
  874.     // because that's the only way to talk to Cyberdog. Therefore once we create the
  875.     // extension, we don't let it go. Hence the unbalanced Acquire.
  876.     cyberPartExtension->Acquire(ev);
  877.     self->fExtension = cyberPartExtension;
  878.     
  879.     return cyberPartExtension;
  880. }
  881.  
  882. #pragma mark -
  883. //========================================================================================
  884. // Callbacks
  885. //========================================================================================
  886. #pragma mark Callbacks
  887.  
  888. //----------------------------------------------------------------------------------------
  889. // Callback Utilities
  890. //----------------------------------------------------------------------------------------
  891.  
  892. // Should I use RTTI here? Hardly seems necessary.
  893. #define FINDSELF(SELF,CALLBACKS)     FW_CCyberdogCallbacks* SELF = \
  894.                                     (FW_CCyberdogCallbacks*) CALLBACKS
  895.  
  896. //----------------------------------------------------------------------------------------
  897. // FW_CallbackOpenCyberItem
  898. //----------------------------------------------------------------------------------------
  899.  
  900. void         FW_CallbackOpenCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item, ODPart* openerPart, ParameterSet* data)
  901. {
  902.     FW_SOM_CALLBACK_TRY
  903.         FINDSELF(self,callbacks);
  904.         self->HandleOpenCyberItem (ev, item, openerPart, data);
  905.     FW_SOM_CALLBACK_ENDTRY
  906. }
  907.  
  908. //----------------------------------------------------------------------------------------
  909. // FW_CallbackSetCyberItem
  910. //----------------------------------------------------------------------------------------
  911.  
  912. void         FW_CallbackSetCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item, ParameterSet* data)
  913. {
  914.     FW_SOM_CALLBACK_TRY
  915.         FINDSELF(self,callbacks);
  916.         self->DoSetCyberItem (ev, item, data);
  917.     FW_SOM_CALLBACK_ENDTRY
  918. }
  919.  
  920. //----------------------------------------------------------------------------------------
  921. // FW_CallbackCanShowCyberItem
  922. //----------------------------------------------------------------------------------------
  923.  
  924. ODBoolean     FW_CallbackCanShowCyberItem     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  925. {
  926.     ODBoolean similar = false;
  927.     FW_SOM_CALLBACK_TRY
  928.         FINDSELF(self,callbacks);
  929.         similar = self->DoCanShowCyberItem (ev, item);
  930.     FW_SOM_CALLBACK_ENDTRY
  931.     
  932.     return similar;
  933. }
  934.  
  935. //----------------------------------------------------------------------------------------
  936. // FW_CallbackShowCyberItem
  937. //----------------------------------------------------------------------------------------
  938.  
  939. void         FW_CallbackShowCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  940. {
  941.     FW_SOM_CALLBACK_TRY
  942.         FINDSELF(self,callbacks);
  943.         self->DoShowCyberItem (ev, item);
  944.     FW_SOM_CALLBACK_ENDTRY
  945. }
  946.  
  947. //----------------------------------------------------------------------------------------
  948. // FW_CallbackGetCyberItemWindow
  949. //----------------------------------------------------------------------------------------
  950.  
  951. ODWindow*     FW_CallbackGetCyberItemWindow     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  952. {
  953.     FW_SOM_CALLBACK_TRY
  954.         FINDSELF(self,callbacks);
  955.         return self->DoGetCyberItemWindow (ev, item);
  956.     FW_SOM_CALLBACK_ENDTRY
  957.     
  958.     return NULL;
  959. }
  960.  
  961. //----------------------------------------------------------------------------------------
  962. // FW_CallbackIsCyberItemSelected
  963. //----------------------------------------------------------------------------------------
  964.  
  965. ODBoolean     FW_CallbackIsCyberItemSelected     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame)
  966. {
  967.     ODBoolean selected = false;
  968.     
  969.     FW_SOM_CALLBACK_TRY
  970.         FINDSELF(self,callbacks);
  971.         selected = self->DoIsCyberItemSelected (ev, frame);
  972.     FW_SOM_CALLBACK_ENDTRY
  973.     
  974.     return selected;
  975. }
  976.  
  977. //----------------------------------------------------------------------------------------
  978. // FW_CallbackAcquireSelectedCyberItems
  979. //----------------------------------------------------------------------------------------
  980.  
  981. void         FW_CallbackAcquireSelectedCyberItems     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame, CyberItemList* list)
  982. {
  983.     FW_SOM_CALLBACK_TRY
  984.         FINDSELF(self,callbacks);
  985.         self->DoAcquireSelectedCyberItems (ev, frame, list);
  986.     FW_SOM_CALLBACK_ENDTRY
  987. }
  988.  
  989. //----------------------------------------------------------------------------------------
  990. // FW_CallbackIsURLSelected
  991. //----------------------------------------------------------------------------------------
  992.  
  993. ODBoolean    FW_CallbackIsURLSelected         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame)
  994. {
  995.     ODBoolean selected = false;
  996.     
  997.     FW_SOM_CALLBACK_TRY
  998.         FINDSELF(self,callbacks);
  999.         selected = self->DoIsURLSelected (ev, frame);
  1000.     FW_SOM_CALLBACK_ENDTRY
  1001.     
  1002.     return selected;
  1003. }
  1004.  
  1005. //----------------------------------------------------------------------------------------
  1006. // FW_CallbackGetSelectedURL
  1007. //----------------------------------------------------------------------------------------
  1008.  
  1009. void         FW_CallbackGetSelectedURL         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame, FW_CString& url)
  1010. {
  1011.     FW_SOM_CALLBACK_TRY
  1012.         FINDSELF(self,callbacks);
  1013.         self->DoGetSelectedURL (ev, frame, url);
  1014. #if 0
  1015.         // all this has been moved into SLCyPart.cpp
  1016.         int length = url.GetByteLength();
  1017.         if (length == 0)
  1018.             return NULL;
  1019.         corbastring curl = (corbastring) SOMMalloc (length + 1);
  1020.         if (!curl)
  1021.             FW_Failure(FW_xMemoryExhausted);
  1022.         strcpy (curl, url);
  1023.         return curl;
  1024. #endif
  1025.     FW_SOM_CALLBACK_ENDTRY
  1026. }
  1027.  
  1028. //----------------------------------------------------------------------------------------
  1029. // FW_CallbackHandleCommand
  1030. //----------------------------------------------------------------------------------------
  1031.  
  1032. ODBoolean     FW_CallbackHandleCommand         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, long commandSuite, long command, ODFrame* frame, somToken parameters)
  1033. {
  1034.     ODBoolean handled = false;
  1035.     
  1036.     FW_SOM_CALLBACK_TRY
  1037.         FINDSELF(self,callbacks);
  1038.         handled = self->HandleCyberCommand (ev, commandSuite, command, frame, parameters);
  1039.     FW_SOM_CALLBACK_ENDTRY
  1040.     
  1041.     return handled;
  1042. }
  1043.  
  1044.