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 / CyberStarter / Sources / Part.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  12.1 KB  |  392 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Part.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9. //
  10. //    Keywords to search for:
  11. //    
  12. //    MUSTCHANGE        Some constants which *must* be changed by you.
  13. //    CONTENTDATA        Simple text model; you will want to change this as well.
  14. //    
  15. //    CYBERDOG        Standard Cyberdog/ODF recipes.
  16. //    USETHREADSFLAG    Some threaded stuff; not finished in this version.
  17. //
  18.  
  19. #ifndef PART_H
  20. #include "Part.h"
  21. #endif
  22.  
  23. #ifndef FRAME_H
  24. #include "Frame.h"
  25. #endif
  26.  
  27. #ifndef DEFINE_H
  28. #include "Define.h"
  29. #endif
  30.  
  31. #ifndef BINDING_H
  32. #include "Binding.h"
  33. #endif
  34.  
  35. #ifndef FWCONTXT_H
  36. #include "FWContxt.h"
  37. #endif
  38.  
  39. #ifndef FWITERS_H
  40. #include "FWIters.h"
  41. #endif
  42.  
  43. #ifndef FWCYSTRM_H
  44. #include "FWCyStrm.h"
  45. #endif
  46.  
  47. #ifndef SOM_CyberStream_xh
  48. #include <CyberStream.xh>
  49. #endif
  50.  
  51. #ifndef SOM_CyberItem_xh
  52. #include <CyberItem.xh>
  53. #endif
  54.  
  55. #ifndef FWSUSINK_H
  56. #include "FWSUSink.h"
  57. #endif
  58.  
  59. #ifndef FWMEMHLP_H
  60. #include "FWMemHlp.h"
  61. #endif
  62.  
  63. #ifndef FWMNUBAR_H
  64. #include "FWMnubar.h"
  65. #endif
  66.  
  67. #ifndef FWCFMRES_H
  68. #include "FWCFMRes.h"
  69. #endif
  70.  
  71. #ifndef _STORUTIL_
  72. #include <StorUtil.h>
  73. #endif
  74.  
  75. #ifndef SOM_Module_OpenDoc_StdProps_defined
  76. #include <StdProps.xh>
  77. #endif
  78.  
  79. // ----- Cyberdog Support----- 
  80.  
  81. #ifndef __CYBERDOG__
  82. #include <Cyberdog.h>
  83. #endif
  84.  
  85. #ifndef SOM_CyberSession_xh
  86. #include <CyberSession.xh>
  87. #endif
  88.  
  89. #include <stdio.h>
  90.  
  91. //========================================================================================
  92. //     
  93. //========================================================================================
  94.  
  95. #ifdef FW_BUILD_MAC
  96. #pragma segment CPart
  97. #endif
  98.  
  99. //========================================================================================
  100. //     Class CPart
  101. //========================================================================================
  102.  
  103. FW_DEFINE_AUTO(CPart)
  104.     
  105. //----------------------------------------------------------------------------------------
  106. // ImmediateRedrawPresentation
  107. //----------------------------------------------------------------------------------------
  108.  
  109. static void ImmediateRedrawPresentation (Environment* ev, FW_CPresentation* p)
  110. {
  111.     FW_CPresentationFrameIterator piter (ev, p);
  112.     for (FW_CFrame* frame = piter.First(ev); piter.IsNotComplete(ev); frame = piter.Next(ev)) {
  113.         FW_CFrameFacetIterator fiter (ev, frame);
  114.         for (ODFacet* facet = (ODFacet*) fiter.First(ev); fiter.IsNotComplete(ev); facet = fiter.Next(ev)) {
  115.             FW_CViewContext gc (ev, frame, facet, nil); 
  116.             ((CFrame*)frame)->DrawUpdate (ev, gc);
  117.         }
  118.     }
  119. }
  120.  
  121. //----------------------------------------------------------------------------------------
  122. // CPart::CPart
  123. //----------------------------------------------------------------------------------------
  124.  
  125. CPart::CPart(ODPart* odPart) :
  126.     FW_CPart(odPart, FW_gInstance, kPartInfoID), 
  127.     fCyberdogHelper (nil), // Cyberdog
  128. #if !USETHREADSFLAG
  129.     FW_CIdler (this, 10), // idling 6 times a second; this is a nice polite value
  130.     fStream (nil),
  131. #endif
  132.     fDownloadedText (nil),
  133.     fAutoReload (true)
  134. {
  135.     FW_END_CONSTRUCTOR
  136. }
  137.  
  138. //----------------------------------------------------------------------------------------
  139. // CPart::CPart
  140. //----------------------------------------------------------------------------------------
  141.  
  142. CPart::~CPart()
  143. {
  144.     ::DisposeHandle (fDownloadedText);
  145.     FW_START_DESTRUCTOR
  146. }
  147.  
  148. //----------------------------------------------------------------------------------------
  149. // CPart::Initialize
  150. //----------------------------------------------------------------------------------------
  151.  
  152. void CPart::Initialize(Environment* ev, ODStorageUnit* storageUnit, FW_Boolean fromStorage)
  153. {
  154.     FW_CPart::Initialize (ev, storageUnit, fromStorage);
  155.     
  156.     // Cyberdog
  157.     fCyberdogHelper = FW_SupportCyberdogIfPresent (ev, this, FW_kUseCyberMenus, kCyberdogCommands, FW_kUseNavigator);
  158.     if (fCyberdogHelper) 
  159.         fCyberdogHelper->SetLoadCyberItemThreadProcedure (&LoadCyberItem, this);
  160.     
  161.     // All our frames look the same (just 1 presentation)
  162.     fPresentation = RegisterPresentation(ev, kODPresDefault, TRUE);
  163.     
  164.     // Our content is just a block of text
  165.     fDownloadedText = ::NewHandle(0);
  166. }
  167.  
  168. //----------------------------------------------------------------------------------------
  169. // CPart::NewFrame
  170. //----------------------------------------------------------------------------------------
  171.  
  172. FW_CFrame* CPart::NewFrame(Environment* ev, 
  173.                                   ODFrame* odFrame, 
  174.                                   FW_CPresentation* presentation, 
  175.                                   FW_Boolean fromStorage)
  176. {
  177.     FW_UNUSED(presentation);
  178.     FW_UNUSED(fromStorage);
  179.     
  180.     return FW_NEW(CFrame, (ev, odFrame, presentation, this));
  181. }
  182.  
  183. //----------------------------------------------------------------------------------------
  184. // CPart::NewPartContent
  185. //----------------------------------------------------------------------------------------
  186.  
  187. FW_CContent* CPart::NewPartContent(Environment* ev)
  188. {
  189. FW_UNUSED(ev);
  190.     return NULL;
  191. }
  192.  
  193. //----------------------------------------------------------------------------------------
  194. // CPart::ExternalizeContent
  195. //----------------------------------------------------------------------------------------
  196.  
  197. void CPart::ExternalizeContent (Environment* ev, ODStorageUnit* su, FW_CCloneInfo* cloneInfo)
  198. {
  199. FW_UNUSED(cloneInfo);
  200.     // Before calling ExternalizeContent, FW_CODPart calls PrivCleanseContentProperty.
  201.     // FW_CPart::ExternalizeContent then calls ClearPartStorage. These amount to an 
  202.     // expensize ODSURemoveProperty. RFE
  203.     ODSURemoveProperty (ev, su, kODPropContents);
  204.     
  205.     {
  206.     // Save content. Pure text, no other data, to make sure our data can be read by any other part.
  207.     ODSUForceFocus (ev, su, kODPropContents, kKind);
  208.     FW_PStorageUnitSink sink (ev, su, kODPropContents, kKind);
  209.     FW_CAcquireLockedSystemHandle locked (fDownloadedText);
  210.     sink->Write (ev, *fDownloadedText, GetHandleSize(fDownloadedText));
  211.     }
  212.     
  213.     {
  214.     // Also save our preferences (auto-reload flag)
  215.     ODSUForceFocus (ev, su, kODPropContents, kSettingsKind);
  216.     FW_PStorageUnitSink sink (ev, su, kODPropContents, kSettingsKind);
  217.     FW_CWritableStream s (sink);
  218.     s << fAutoReload;
  219.     }
  220.     
  221.     if (fCyberdogHelper && fCyberdogHelper->GetCyberItem(ev)) {
  222.     // Save our CyberItem so we can reload ourself later
  223.     // Cyberdog defines the kCyberItemKind constant
  224.         ODSUForceFocus (ev, su, kODPropContents, kCyberItemKind);
  225.         FW_PStorageUnitSink sink (ev, su, kODPropContents, kCyberItemKind);
  226.         fCyberdogHelper->ExternalizeCurrentCyberItem (ev, sink);
  227.     }
  228.     else
  229.         printf ("Can't find a CyberItem\n");
  230. }
  231.  
  232. //----------------------------------------------------------------------------------------
  233. // CPart::InternalizeContent
  234. //----------------------------------------------------------------------------------------
  235.  
  236. FW_Boolean CPart::InternalizeContent(Environment* ev, ODStorageUnit* su, FW_CCloneInfo* cloneInfo)
  237. {
  238. FW_UNUSED(cloneInfo);
  239.     // Read our content (if any).
  240.     if (ODSUExistsThenFocus (ev, su, kODPropContents, kKind)
  241.             /*|| ODSUExistsThenFocus (ev, su, kODPropContents, FW_CPart::fgMacTEXTDataType)*/)
  242.     {
  243.         Size size = su->GetSize (ev);
  244.         ::SetHandleSize (fDownloadedText, size);
  245.         FW_CAcquireLockedSystemHandle locked (fDownloadedText);
  246.         FW_PStorageUnitSink sink (ev, su, kODPropContents, kKind);
  247.         sink->Read (ev, *fDownloadedText, size);
  248.     }
  249.     // Read our settings (the "auto-download" flag)
  250.     if (ODSUExistsThenFocus (ev, su, kODPropContents, kSettingsKind)) {
  251.         FW_PStorageUnitSink sink (ev, su, kODPropContents, kSettingsKind);
  252.         FW_CReadableStream s (sink);
  253.         s >> fAutoReload;
  254.     }
  255.     // Read the CyberItem
  256.     if (fCyberdogHelper && ODSUExistsThenFocus (ev, su, kODPropContents, kCyberItemKind)) {
  257.         FW_PStorageUnitSink sink (ev, su, kODPropContents, kCyberItemKind);
  258.         CyberItem* ci = fCyberdogHelper->InternalizeCyberItem (ev, sink, fAutoReload);
  259.     }
  260.     else
  261.         printf ("Can't find a CyberItem\n");
  262.     
  263.     return true;
  264. }
  265.  
  266. //----------------------------------------------------------------------------------------
  267. // CPart::DoAdjustMenus
  268. //----------------------------------------------------------------------------------------
  269.  
  270. FW_Handled CPart::DoAdjustMenus(Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
  271. {
  272. FW_UNUSED(isRoot);
  273.     if (!hasMenuFocus)
  274.         return FW_kNotHandled;
  275.     
  276.     if (fCyberdogHelper) {
  277.         menuBar->EnableAndCheckCommand (ev, kAutoReload, TRUE, fAutoReload);
  278.         menuBar->EnableCommand (ev, kDoReload, fCyberdogHelper->GetCyberItem(ev) != kODNULL);
  279.     }
  280.     
  281.     return FW_kNotHandled;
  282. }
  283.  
  284. //----------------------------------------------------------------------------------------
  285. // CPart::DoMenu
  286. //----------------------------------------------------------------------------------------
  287.  
  288. FW_Handled CPart::DoMenu (Environment* ev, const FW_CMenuEvent& event)
  289. {
  290.     ODCommandID c = event.GetCommandID(ev);
  291.     
  292.     if (fCyberdogHelper) {
  293.         if (c == kDoReload) {
  294.             fCyberdogHelper->GetExtension(ev)->SetCyberItem (ev, fCyberdogHelper->GetCyberItem(ev), kODNULL);
  295.             return FW_kHandled;
  296.         }
  297.         else if (c == kAutoReload) {
  298.             fAutoReload = !fAutoReload;
  299.             return FW_kHandled;
  300.         }
  301.     }
  302.     
  303.     return FW_CPart::DoMenu (ev, event);
  304. }
  305.  
  306. #if !USETHREADSFLAG
  307.  
  308. //----------------------------------------------------------------------------------------
  309. // CPart::DoIdle
  310. //----------------------------------------------------------------------------------------
  311. //
  312. //    CYBERDOG
  313. //    
  314. //    You need to change DoIdle/LoadCyberItem to read your content from the network.
  315. //    
  316. //    DoSetCyberItem is called when you need to read a CyberItem. It starts idling,
  317. //    and you will read the data in DoIdle. If you are using threads (preferred but not
  318. //    quite handled properly by Cyberdog yet), then you will do the work in LoadCyberItem.
  319. //    
  320. //    Note that you must call inherited to get the default behavior of OpenCyberItem as 
  321. //    well. Navigator-aware parts will not call inherited but will do things differently.
  322.  
  323. FW_Boolean CPart::DoIdle (Environment* ev, const FW_CNullEvent& event)
  324. {
  325.     if (fStream) {
  326.         short status;
  327.         do {
  328.         status = fStream->GetStreamStatus (ev);
  329.         if (status & kCDDataAvailable) {
  330.             Size oldSize = ::GetHandleSize (fDownloadedText);
  331.             FW_CCyberBuffer ab (ev, fStream);
  332.             // CONTENTDATA - change this portion to deal with your data form
  333.             // Add any data available to the text handle, and redraw it
  334.             ::SetHandleSize (fDownloadedText, oldSize + ab.GetSize());
  335.             if (::MemError()) // XXX what's the best way to report an error from an idle method?
  336.                 status = kCDErrorOccurred;
  337.             else
  338.                 memcpy (*fDownloadedText + oldSize, ab.GetBuffer(), ab.GetSize());
  339.             // Draw the new data right now
  340.             ImmediateRedrawPresentation (ev, fPresentation);
  341.         }
  342.         else if (status & FW_kCyberStreamDone) {
  343.             printf ("DoIdle: done downloading.\n");
  344.             fStream = nil; // smart pointer will call Abort if necessary automatically
  345.             // We can't UnregisterIdle from a DoIdle (OD limitation), so until I figure out a 
  346.             // workaround we simply keep on idling (doing nothing).
  347.             //UnregisterIdle (ev);
  348.             printf ("Download time: %i ticks.\n", TickCount()-fStartTime);
  349.         }
  350.         } while (status & kCDDataAvailable);
  351.     }
  352.     
  353.     return false; // let other idlers get time also XXX need FW_kContinueEvent!
  354. }
  355.  
  356. #else
  357.  
  358. //----------------------------------------------------------------------------------------
  359. // CPart::LoadCyberItem
  360. //----------------------------------------------------------------------------------------
  361.  
  362. void CPart::LoadCyberItem (Environment* ev, void* selfCPart)
  363. {
  364.     // Note this is a static method. "this" is passed in from DoSetCyberItem
  365.     CPart* self = (CPart*) selfCPart;
  366.     
  367.     CyberItem* item = self->fCyberdogHelper->GetCyberItem(ev);
  368.     CyberStream* cStream = item->CreateCyberStream (ev);
  369.     cStream->Open (ev);
  370.     FW_PCyberSink sink (ev, cStream);
  371.     
  372.     // We don't need to deal with error handling at all here. An error causes an
  373.     // exception to be thrown, and all our nice stack-based objects delete themselves.
  374.     
  375.     long total = 0;
  376.     long available;
  377.     while ((available = sink->GetReadableBytes (ev)) != 0) {
  378.         // CONTENTDATA - change this portion to deal with your data form
  379.         // We'll download and display whatever is available.
  380.         ::SetHandleSize (self->fDownloadedText, total + available);
  381.         ::HLock(self->fDownloadedText);
  382.         sink->Read (ev, *self->fDownloadedText + total, available);
  383.         ::HUnlock (self->fDownloadedText);
  384.         total += available;
  385.         // Draw the new data right now
  386.         ImmediateRedrawPresentation (ev, self->fPresentation);
  387.     }
  388. }
  389.  
  390. #endif
  391.  
  392.