Your Search Results

    Activity Manager examples

    This content covers features introduced in Thunderbird 3

    The Activity Manager is a simple component that understands how to display a combination of user activity and history. See the Activity Manager page for a general description of the component. See the Activity Manager interfaces page for an overview of the related interfaces.

    If the default implementation of nsIActivityProcess, nsIActivityWarning and nsIActivityEvent are not sufficient for the activity initiator, activity developers can provide their own components to extend the capabilities. Default implementations can be found in nsActivity.js file.

    If activity developers would like to extend the default UI representation of the activity types, they can provide their own XBL elements for their own activity types. All custom activity XBL elements should inherit from "activity-base" binding. For XBL samples please see activity.xml and activityBinding.css files.

    Showing a user-defined activity in the Activity Manager window

    The following sample will show a process and an event for junk processing in the Activity Manager window.

    // Step 1: Adding a Process into the activity manager
    const nsIAP = Components.interfaces.nsIActivityProcess;
    const nsIAE = Components.interfaces.nsIActivityEvent;
    const nsIAM = Components.interfaces.nsIActivityManager;
    
    let gActivityManager = Components.classes["@mozilla.org/activity-manager;1"].getService(nsIAM);
    let process = Components.classes["@mozilla.org/activity-process;1"].createInstance(nsIAP);
    
    // Assuming folder is an instance of nsIMsgFolder interface
    
    // Localization is omitted, initiator is not provided
    process.init("Processing folder: " + folder.prettiestName, 
                 null);
    // Note that we don't define a custom icon, default process icon
    // will be used
    process.contextType = "account";     // group this activity by account 
    process.contextObj = folder.server;  // account in question
    
    gActivityManager.addActivity(process);
    
    // Step 2: Showing some progress
    
    let percent = 50;
    process.setProgress(percent, "Junk processing 25 of 50 messages", 25, 50);
    
    // Step 3: Removing the process and adding an Event using Process' attributes
    process.state = Components.interfaces.nsIActivityProcess.STATE_COMPLETED;
    gActivityManager.removeActivity(process.id);
    
    let event = Components.classes["@mozilla.org/activity-event;1"].createInstance(nsIAE);
    
    // Localization is omitted, initiator is omitted
    event.init(folder.prettiestName + " is processed",
               null, 
               "No junk found", 
               process.startTime,  // start time 
               Date.now());        // completion time
    
    event.contextType = process.contextType; // optional
    event.contextObj = process.contextObj;   // optional
                 
    gActivityManager.addActivity(event);
    

    Showing a user-defined activity with cancel capability (JavaScript)

    This sample improves the previous one by providing an nsIActivityCancelHandler to allow the user to cancel the process.

    // Step 1: Create a nsIActivityCancelHandler implementation
    function CancelJunkProcess() 
    {
     // user stuff here..
    }
    CancelJunkProcess.prototype = {
     cancel: function(aActivity) {
       let initiator = aActivity.initiator;
       if (initiator) {
         let folder = aActivity.getSubjects({})[0];
         ....
         // assuming that the initiator has some way to cancel 
         // the junk processing for given folder
         if (initiator.cancelFolderOp(folder)) {
           aActivity.state = Components.interfaces.nsIActivityProcess.STATE_CANCELED;
           gActivityManager.removeActivity(aActivity.id);
           return Cr.NS_SUCCESS;
         }
       }
      return Cr.NS_FAILURE;
     }
    }
    
    // Step 2: Modify the previous sample to add initiator, subject
    // and associate a nsIActivityCancelHandler component
    ...
    // assuming that gJunkProcessor is the entity initiating the junk processing 
    // activity, and it has cancelFolderOp method that cancels the operations on folders
    process.init("Processing folder: " + folder.prettiestName, 
                 gJunkProcessor);
    
    // folder is being filtered/processed 
    process.addSubject(folder);
    process.cancelHandler = new CancelJunkProcess();
    ...
    

    Since nsIActivityCancelHandler is provided with the activity, the UI will show a cancel button beside the activity. You can extrapolate this sample to nsIActivityRetryHandler and nsIActivityPauseHandler as well.

    Showing a user-defined activity with undo capability (C++)

    .....
    #include "nsIActivity.h"
    #include "nsIActivityManager.h"
    .....
    
    //////////////////////////////////////////////////////////////////////////////
    //// Undo handler implementation
    
    class myCopyEventUndo : public nsIActivityUndoHandler
    {  
     public:
      NS_DECL_ISUPPORTS
      NS_DECL_NSIACTIVITYUNDOHANDLER
      myCopyEventUndo() {}
     private:
      ~myCopyEventUndo() {}
    };
    NS_IMPL_ISUPPORTS1(myCopyEventUndo, nsIActivityUndoHandler)
    
    NS_IMETHODIMP myCopyEventUndo::Undo(nsIActivityEvent *event, nsresult *result)
    {
      nsresult rv;
      // get the subjects of this copy event
      PRUint32 length;
      nsIVariant **subjectList;
      rv = event->GetSubjects(&length, &subjectList);
      if(NS_FAILED(rv)) 
        return rv;
      
      // first subject in the list is the source folder in this particular case
      nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(subjectList[0]);
      
      // get the initiator
      nsIVariant *initiator;
      event->GetInitiator(&initiator);
       
      if (initiator)
      {
        nsISupports* ptr;
        rv = object->GetAsISupports(&ptr);
        if(NS_FAILED(rv)) 
          return rv;
         
        nsCOMPtr<nsIMsgCopyService> copyService = do_QueryInterface(ptr);
        if (copyService)
          copyService->Undo(folder); 
      }
      
      return (*result = NS_OK);
     }
    
    /////////////////////////////////////////////////////////////////////////////
    //// Creating an undoable copy event
    
    nsCOMPtr<nsIActivityUndoHandler> undoHandler = new myCopyEventUndo();
    nsCOMPtr<nsIActivityEvent> copyEvent(do_CreateInstance("@mozilla.org/activity-event;1"));
    
    // The initiator of this particular event is CopyService. We want to
    // associate it with the event since we are going to use it in the
    // undo handler.
    // Same for the source folder, it is required for undo operation, but
    // since it is the subject of this activity (event), it goes into the
    // subject list.
    
    // wrap copyservice in a nsvariant component
    nsCOMPtr<nsIWritableVariant> initiator = do_CreateInstance(NS_VARIANT_CONTRACTID);
    initiator->SetAsISupports(reinterpret_cast<nsISupports*>(copyService));
     
    // subject of the delete operation is the imap folder
    // wrap it in a nsvariant component
    nsCOMPtr<nsIWritableVariant> srcFolder = do_CreateInstance(NS_VARIANT_CONTRACTID);
    srcFolder->SetAsISupports(reinterpret_cast<nsISupports*>(imapFolder));
    copyEvent->AddSubject(srcFolder);
    
    copyEvent->Init(NS_LITERAL_STRING("Message copy event"),
                    initiator,
                    NS_LITERAL_STRING("Completed successfully"), 
                    PR_Now() / PR_USEC_PER_MSEC,   // start time
                    PR_Now() / PR_USEC_PER_MSEC);  // completion time
    
    // Do not forget to increase the ref counter if needed
    copyEvent->SetUndoHandler(undoHandler);  
    
    ////////////////////////////////////////////////////////////////
    //// Adding the event into Activity Manager
    
    nsCOMPtr<nsIActivityManager> activityMgr(do_GetService("@mozilla.org/activity-manager;1"));
    PRUint32 id;
    activityMgr->AddActivity(copyEvent, &id);
    

    Adding an activity with a custom context type

    This sample shows how to provide a custom context type for junk processing. As a result, all junk processing activities (assuming that we process accounts in parallel) dealing with messages coming from the same sender will be grouped together. (This example seems to be outdated and not working, see bug 557467 comment 1.)

    //optional: define some convenience constants
    const nsActProcess = Components.Constructor("@mozilla.org/activity-process;1",
                                               "nsIActivityProcess", "init");
    const nsActEvent = Components.Constructor("@mozilla.org/activity-event;1",
                                             "nsIActivityEvent", "init");
    
     // Step 1: Implement nsIActivityContextDisplayHelper to show a 
     //         customized   display text for our context type
    function SenderContextDisplayHelper() 
    {
     // user stuff here..
    }
    SenderContextDisplayHelper.prototype = {
     getContextDisplayText: function(contextType, contextObj) {
       // in this particular example we know that contextType is "Sender"
       // since we also pass the contextType along with the contextObject 
       //  in some cases, one helper can be registered for a group of context types
    
       // we know that the context object is the author of the message
       // Localization is omitted
       return "Messages coming from " + contextObj.surname + ", " + contextObj.firstname;
     }
    }
    
    // Step 2: Register the helper for this context type
    gActivityManager.registerContextDisplayHelper("Sender", 
                                                 new SenderContextDisplayHelper());
    
    
    // Step 3: Create the process
    ...
    let process = new nsActProcess("Processing folder: " + folder.prettiestName,
                                   gJunkProcessor);
    
    process.cancelHandler = new CancelJunkProcess();
    
    // folder is being filtered/processed 
    process.addSubject(folder);
    process.contextType = "Sender";
    // assuming msg is an instance of nsIMsgHdr
    process.contextObj = msg.author;
    ...
    

    Adding a fully customized activity

    In complex scenarios, extensions might implement their own version of the nsIActivityProcess, nsIActivityWarning and nsIActivityEvent interfaces. In such cases, nsActivity.js can be used as a model.

    Document Tags and Contributors

    Contributors to this page: wbamberg, jenzed, aceman-bugzilla, Standard8, farqad
    Last updated by: aceman-bugzilla,