Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Cyberdog Programmer's Kit / Part 2 - Programming in Cyberdog
Chapter 5 - Embedding a Cyberdog Display Part in a Navigator


Using a Progress Broadcaster

Your embedded display part can set up a progress broadcaster to send status information to progress receivers. This information might include the amount of data transferred by a download operation or a stream's status. Progress receivers are associated with progress parts, such as Cyberdog navigators and Cyberdog opener parts. Progress parts display the status of time-consuming operations. Thus, the navigator and opener parts support behavior to receive and display progress. The navigator or opener part can use the information received to animate and display the status bar.

To use a progress broadcaster, you must support the following operations:

The following sections show you how to implement these operations.

Setting Up the Progress Broadcaster

You can set up a progress broadcaster when you initiate any time-consuming operation. To set up a progress broadcaster, you must take the following actions:

The embedded text-viewer part creates a progress broadcaster when it starts a download operation. Listing 5-6 shows the InitiateDownload method, which is called from the OpenCyberItem method.

Listing 5-6 The InitiateDownload method of the embedded text-viewer part

void CybTxtNavViewer::InitiateDownload (Environment *ev, 
                              CyberItem* item, 
                              ParameterSet* openParams) 
{
   // Start the download and add the item to the log.
   ...
   
   // Prepare a progress broadcaster to attach to the navigator part.
   if (fBroadcaster == kODNULL)
   {
      fBroadcaster = new CyberProgressBroadcaster;
      
      if (gMyCyberAbortUPP == nil)
      {
         gMyCyberAbortUPP = NewCyberAbortProc(CyberAbortProc);
      }
      fBroadcaster->ICyberProgressBroadcaster
                           (ev, gMyCyberAbortUPP, (Ptr) this);
      // Set the progress mode.
      fBroadcaster->SetProgressMode(ev, kUnmeteredProgress);
   }
}
Listing 5-6 shows the this pointer being passed as an argument to the ICyberProgressBroadcaster method. The this pointer allows the calling object to be referenced from the abort procedure callback routine.

Note
The gMyCyberAbortUPP class variable holds a pointer to the callback procedure. It is initialized as follows:
CyberAbortUPP CybTxtNavViewer::gMyCyberAbortUPP = nil;

Implementing the Abort Callback Function

When the user cancels an operation associated with a Cyberdog broadcaster, such as by closing the navigator's window during a download operation, the broadcaster's abort callback function is called. The abort callback function takes the appropriate action to abort the operation. Listing 5-7 shows the embedded text-viewer's abort callback function, called CyberAbortProc. It aborts the stream.

Listing 5-7 The embedded text-viewer's abort callback function

void CybTxtNavViewer::CyberAbortProc(CDAbortProcMessage msgCode,
                            CyberProgressBroadcaster*, 
                            Ptr thisPtr)
{
   CybTxtNavViewer* THIS = (CybTxtNavViewer*)thisPtr;
   
   switch(msgCode)
   {
      case kAbortMessage:
         if (THIS->fStream)
            THIS->fStream->Abort(somGetGlobalEnvironment());
         break;
      default:
         break;
   }
   return;
}
The PollStream method deletes the stream and the broadcaster when the download operation is aborted. See Listing 5-10 (page 160).

Attaching the Broadcaster Object

You can attach a Cyberdog broadcaster object to a Cyberdog navigator when your display part appears in a navigator. Your part is notified when a new display frame is created or when a display frame that was previously written out is instantiated from storage. OpenDoc calls the DisplayFrameAdded and DisplayFrameConnected methods, respectively, to handle these cases; you can attach the broadcaster object these methods.

To attach a progress broadcaster, you must take the following actions:

Listing 5-8 shows how the embedded text-viewer part attaches a progress broadcaster to a Cyberdog navigator. The part calls its GetContainingNavigator method to find a frame that is a navigator; see Listing 5-5 (page 154).

Listing 5-8 Adding a progress broadcaster

if (fBroadcaster)
{
   ODPart* navPart = this->GetContainingNavigator(ev);
   if (navPart)
   {
      TempNavigatorExtension navExt(navPart, kCyberNavigatorExtension);
      navExt->AttachProgressBroadcaster(ev, fBroadcaster);
   }
}

Detaching the Broadcast Object

When your display part is no longer displayed in a navigator, you should detach the progress broadcaster object by calling your part extension's DetachProgressBroadcaster method. You may need to detach the broadcaster object when OpenDoc calls the DisplayFrameRemoved or the DisplayFrameClosed methods.

Listing 5-9 shows the embedded text-viewer part's DisplayFrameRemoved method, which detaches the broadcaster.

Listing 5-9 The DisplayFrameRemoved method of the embedded text-viewer part

void CybTxtNavViewer::DisplayFrameRemoved( Environment*ev,
                             ODFrame*  frame )
{
   TRY
      // Keep a reference to the navigator; it may be necessary to
      // detach our broadcaster from the navigator.
      ODPart* preNavPart = kODNULL;
      if(fBroadcaster)
         preNavPart = this->GetContainingNavigator(ev);
      

      // Perform the operations associated with removal.
      ...

      // Detach the broadcaster if the part is no longer displayed
      // in the navigator.
      if (fBroadcaster)
      {
         if (preNavPart && (preNavPart != GetContainingNavigator(ev)))
         {
            TempNavigatorExtension 
                     navExt(preNavPart, kCyberNavigatorExtension);
            navExt->DetachProgressBroadcaster(ev, fBroadcaster);
         }
      }
      this->SetDirty(ev);
   
   CATCH_ALL
   ...
      RERAISE;
   ENDTRY
}

Sending Status Messages to the Navigator

You can send messages to a navigator by calling broadcaster methods. Listing 5-10 shows how the embedded text-viewer part sends messages during a polling operation. The method calls the broadcaster's SetAmountDone method to update the number of characters transferred. It then calls the broadcaster's SetStatusString method to update the status string. The method calls the stream's GetStatusString method to obtain the content information to display.

Listing 5-10 Sending status messages to the navigator

void CybTxtNavViewer::PollStream(Environment* ev)
{  
   StreamStatus status;
   ODBoolean gotData = kODFalse;
   Size bytesThisPoll = 0;
   ODULong savedLength = fCharsLength;
   
   while (bytesThisPoll < kBytesPerPoll) 
   {  
      status = fStream->GetStreamStatus(ev);
      // Get the data.
      ...
   }
   
   // Check status after data transfer; it may have changed.
   status = fStream->GetStreamStatus(ev); 

   // Animate the Amount Done field of the navigator's status bar.
   if (fCharsLength > savedLength)
      fBroadcaster->SetAmountDone(ev, fCharsLength);
      
   // Get the status string from the stream and display it in the
   // navigator's status bar.
   if (status & kCDStatusStringChanged)
   {
      Str255 status;
      fStream->GetStatusString(ev, status);
      fBroadcaster->SetStatusString(ev, status);
   }
   // Downloading is complete or an error occurred.
   if ((status & kCDDownloadComplete) || 
      (status & kCDErrorOccurred) || 
      (status & kCDAbortComplete)) 
   {
      // Delete the stream.
      delete fStream;
      fStream = kODNULL;
      
      // Delete the progress broadcaster.
      if (fBroadcaster)
      {
         delete fBroadcaster;
         fBroadcaster = kODNULL;
      }
   }
   ...
}

Previous Book Contents Book Index Next

© Apple Computer, Inc.
13 JUL 1996