File:  [mozdev] / chimera / ProgressDlgController.mm
Revision 1.9: download - view: text, annotated - select for diffs - revision graph
Mon Feb 4 03:44:35 2002 UTC (17 years, 10 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Saving actually works.  Just need to wire up the progress meter and elapsed time stuff.

    1: //
    2: //  ProgressDlgController.m
    3: //  Chimera
    4: //
    5: //  Created by David Hyatt on Sat Feb 02 2002.
    6: //  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
    7: //
    8: 
    9: #import "ProgressDlgController.h"
   10: 
   11: #include "nsCOMPtr.h"
   12: #include "nsString.h"
   13: #include "nsIWebBrowserPersist.h"
   14: #include "nsIInputStream.h"
   15: #include "nsIURL.h"
   16: #include "nsILocalFile.h"
   17: #include "nsIDOMHTMLDocument.h"
   18: #include "nsIWebProgressListener.h"
   19: #include "nsIComponentManager.h"
   20: #include "nsIPrefBranch.h"
   21: 
   22: const char* prefContractID = "@mozilla.org/preferences-service;1";
   23: 
   24: class nsDownloadListener : public nsIWebProgressListener
   25: {
   26: public:
   27:     nsDownloadListener(ProgressDlgController* aController,
   28:                        nsIWebBrowserPersist* aPersist,
   29:                        nsISupports* aSource,
   30:                        NSString* aDestination,
   31:                        const char* aContentType,
   32:                        nsIInputStream* aPostData,
   33:                        BOOL aBypassCache)
   34:     {
   35:         NS_INIT_REFCNT();
   36:         mController = aController;
   37:         mWebPersist = aPersist;
   38:         // The source is either a simple URL or a complete document.
   39:         mURL = do_QueryInterface(aSource);
   40:         if (!mURL)
   41:             mDocument = do_QueryInterface(aSource);
   42:         nsCAutoString dstStr = [aDestination cString];
   43:         NS_NewLocalFile(dstStr.get(), PR_FALSE, getter_AddRefs(mDestination));
   44:         mContentType = aContentType;
   45:         mPostData = aPostData;
   46:         mBypassCache = aBypassCache;
   47:     };
   48:     
   49:     virtual ~nsDownloadListener() {};
   50: 
   51:     NS_DECL_ISUPPORTS
   52:     NS_DECL_NSIWEBPROGRESSLISTENER
   53:   
   54: public:
   55:     void BeginDownload();
   56:     void InitDialog();
   57:     
   58: private: // Member variables
   59:     ProgressDlgController* mController; // Controller for our UI.
   60:     nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
   61:     nsCOMPtr<nsIURL> mURL; // The URL of our source file. Null if we're saving a complete document.
   62:     nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
   63:     nsCString mContentType; // Our content type string.
   64:     nsCOMPtr<nsIDOMHTMLDocument> mDocument; // A DOM document.  Null if we're only saving a simple URL.
   65:     nsCOMPtr<nsIInputStream> mPostData;  // For complete documents, this is our post data from session history.
   66:     PRBool mBypassCache; // Whether we should bypass the cache or not.
   67: };
   68: 
   69: NS_IMPL_ISUPPORTS1(nsDownloadListener, nsIWebProgressListener)
   70: 
   71: /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
   72: NS_IMETHODIMP 
   73: nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress, 
   74: 					 nsIRequest *aRequest, 
   75: 					 PRInt32 aCurSelfProgress, 
   76: 					 PRInt32 aMaxSelfProgress, 
   77: 					 PRInt32 aCurTotalProgress, 
   78: 					 PRInt32 aMaxTotalProgress)
   79: {
   80:   return NS_OK;
   81: }
   82: 
   83: /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
   84: NS_IMETHODIMP 
   85: nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress, 
   86: 					 nsIRequest *aRequest, 
   87: 					 nsIURI *location)
   88: {
   89:   return NS_OK;
   90: }
   91: 
   92: /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
   93: NS_IMETHODIMP 
   94: nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress, 
   95: 				       nsIRequest *aRequest, 
   96: 				       nsresult aStatus, 
   97: 				       const PRUnichar *aMessage)
   98: {
   99:   return NS_OK;
  100: }
  101: 
  102: /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */
  103: NS_IMETHODIMP 
  104: nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, 
  105: 					              nsIRequest *aRequest, 
  106:                                   PRInt32 state)
  107: {
  108:   return NS_OK;
  109: }
  110: 
  111: // Implementation of nsIWebProgressListener
  112: /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
  113: NS_IMETHODIMP 
  114: nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, 
  115: 				      nsIRequest *aRequest, 
  116: 				      PRInt32 aStateFlags, 
  117: 				      PRUint32 aStatus)
  118: {
  119:     return NS_OK;
  120: }
  121: 
  122: void
  123: nsDownloadListener::BeginDownload()
  124: {
  125:     if (mWebPersist) {
  126:         mWebPersist->SetProgressListener(this);
  127:         PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION | 
  128:                         nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
  129:         if (mBypassCache)
  130:             flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
  131:         else
  132:             flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
  133:             
  134:         if (mURL)
  135:             mWebPersist->SaveURI(mURL, mPostData, mDestination);
  136:         else {
  137:             PRInt32 encodingFlags = 0;
  138:             nsCOMPtr<nsILocalFile> filesFolder;
  139:             
  140:             if (!mContentType.Equals("text/plain")) {
  141:                 // Create a local directory in the same dir as our file.  It
  142:                 // will hold our associated files.
  143:                 filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
  144:                 nsXPIDLString unicodePath;
  145:                 mDestination->GetUnicodePath(getter_Copies(unicodePath));
  146:                 filesFolder->InitWithUnicodePath(unicodePath.get());
  147:                 
  148:                 nsXPIDLCString leafName;
  149:                 filesFolder->GetLeafName(getter_Copies(leafName));
  150:                 nsCAutoString nameMinusExt(leafName.get());
  151:                 PRInt32 index = nameMinusExt.RFind(".");
  152:                 if (index >= 0)
  153:                     nameMinusExt.Left(nameMinusExt, index);
  154:                 nameMinusExt += " Files"; // XXXdwh needs to be localizable!
  155:                 filesFolder->SetLeafName(nameMinusExt.get());
  156:                 PRBool exists = PR_FALSE;
  157:                 filesFolder->Exists(&exists);
  158:                 if (!exists)
  159:                     filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
  160:             }
  161:             else
  162:                 encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
  163:                                  nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
  164:                                  nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
  165:                                  
  166:             mWebPersist->SaveDocument(mDocument, mDestination, filesFolder, mContentType.get(),
  167:                                       encodingFlags, 80);
  168:         }
  169:     }
  170:     
  171:     InitDialog();
  172: }
  173: 
  174: void
  175: nsDownloadListener::InitDialog()
  176: {
  177:     if (!mURL && !mDocument)
  178:         return;
  179:         
  180:     if (mWebPersist) {
  181:         if (mURL) {
  182:             nsXPIDLCString spec;
  183:             mURL->GetSpec(getter_Copies(spec));
  184:             [mController setSourceURL: spec.get()];
  185:         }
  186:         else {
  187:             nsAutoString spec;
  188:             mDocument->GetURL(spec);
  189:             nsCAutoString spec2; spec2.AssignWithConversion(spec);
  190:             [mController setSourceURL: spec2.get()];
  191:         }
  192:     }
  193:     
  194:     nsXPIDLString path;
  195:     mDestination->GetUnicodePath(getter_Copies(path));
  196:     nsCAutoString pathStr; pathStr.AssignWithConversion(path.get());
  197:     [mController setDestination: pathStr.get()];
  198:     
  199:     
  200: }
  201: 
  202: static NSString *SaveFileToolbarIdentifier			= @"Save File Dialog Toolbar";
  203: static NSString *CancelToolbarItemIdentifier		= @"Cancel Toolbar Item";
  204: static NSString *PauseResumeToolbarItemIdentifier	= @"Pause and Resume Toggle Toolbar Item";
  205: static NSString *ShowFileToolbarItemIdentifier		= @"Show File Toolbar Item";
  206: static NSString *OpenFileToolbarItemIdentifier		= @"Open File Toolbar Item";
  207: static NSString *LeaveOpenToolbarItemIdentifier		= @"Leave Open Toggle Toolbar Item";
  208: 
  209: @interface ProgressDlgController(Private)
  210: -(void)setupToolbar;
  211: @end
  212: 
  213: @implementation ProgressDlgController
  214: 
  215: -(void)setWebPersist:(nsIWebBrowserPersist*)aPersist 
  216:               source:(nsISupports*)aSource
  217:          destination:(NSString*)aDestination
  218:          contentType:(const char*)aContentType
  219:             postData:(nsIInputStream*)aInputStream
  220:          bypassCache:(BOOL)aBypassCache
  221: {
  222:     mDownloadListener = new nsDownloadListener(self, aPersist, aSource,
  223:                                                aDestination, aContentType,
  224:                                                aInputStream, aBypassCache);
  225:     NS_ADDREF(mDownloadListener);
  226: }
  227: 
  228: -(void) setSourceURL: (const char*)aSource
  229: {
  230:     [mFromField setStringValue: [NSString stringWithCString: aSource]];
  231: }
  232: 
  233: -(void) setDestination: (const char*)aDestination
  234: {
  235:     [mToField setStringValue: [NSString stringWithCString: aDestination]];
  236: }
  237: 
  238: - (void)windowDidLoad
  239: {
  240:     mDownloadIsPaused = NO; 
  241:     nsCOMPtr<nsIPrefBranch> prefs(do_GetService(prefContractID));
  242:     PRBool save = PR_FALSE;
  243:     prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive", 
  244:                         &save);
  245:     mSaveFileDialogShouldStayOpen = save;
  246: 
  247:     [self setupToolbar];
  248:     if (mDownloadListener)
  249:         mDownloadListener->BeginDownload();
  250: }
  251: 
  252: - (void)setupToolbar
  253: {
  254:     NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:SaveFileToolbarIdentifier] autorelease];
  255: 
  256:     [toolbar setDisplayMode:NSToolbarDisplayModeDefault];
  257:     [toolbar setAllowsUserCustomization:YES];
  258:     [toolbar setAutosavesConfiguration:YES];
  259:     [toolbar setDelegate:self];
  260:     [[self window] setToolbar:toolbar];
  261: }
  262: 
  263: - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
  264: {
  265:     return [NSArray arrayWithObjects: CancelToolbarItemIdentifier,
  266:         PauseResumeToolbarItemIdentifier,
  267:         ShowFileToolbarItemIdentifier,
  268:         OpenFileToolbarItemIdentifier,
  269:         LeaveOpenToolbarItemIdentifier,
  270:         NSToolbarCustomizeToolbarItemIdentifier,
  271:         NSToolbarFlexibleSpaceItemIdentifier,
  272:         NSToolbarSpaceItemIdentifier,
  273:         NSToolbarSeparatorItemIdentifier,
  274:         nil];
  275: }
  276: 
  277: - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
  278: {
  279:     return [NSArray arrayWithObjects: CancelToolbarItemIdentifier,
  280:         PauseResumeToolbarItemIdentifier,
  281:         NSToolbarFlexibleSpaceItemIdentifier,
  282:         LeaveOpenToolbarItemIdentifier,
  283:         ShowFileToolbarItemIdentifier,
  284:         OpenFileToolbarItemIdentifier,
  285:         nil];
  286: }
  287: 
  288: - (NSToolbarItem *) toolbar:(NSToolbar *)toolbar
  289:       itemForItemIdentifier:(NSString *)itemIdent
  290:   willBeInsertedIntoToolbar:(BOOL)willBeInserted
  291: {
  292:     NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdent] autorelease];
  293: 
  294:     if ( [itemIdent isEqual:CancelToolbarItemIdentifier] ) {
  295:         [toolbarItem setLabel:@"Cancel"];
  296:         [toolbarItem setPaletteLabel:@"Cancel Download"];
  297:         [toolbarItem setToolTip:@"Cancel this file download"];
  298:         [toolbarItem setImage:[NSImage imageNamed:@"saveCancel"]];
  299:         [toolbarItem setTarget:self];
  300:         [toolbarItem setAction:@selector(cancel)];
  301:     } else if ( [itemIdent isEqual:PauseResumeToolbarItemIdentifier] ) {
  302:         [toolbarItem setLabel:@"Pause"];
  303:         [toolbarItem setPaletteLabel:@"Pause Download"];
  304:         [toolbarItem setToolTip:@"Pause this FTP file download"];
  305:         [toolbarItem setImage:[NSImage imageNamed:@"savePause"]];
  306:         [toolbarItem setTarget:self];
  307:         [toolbarItem setAction:@selector(pauseAndResumeDownload)];
  308:         pauseResumeToggleToolbarItem = toolbarItem; //establish reference
  309:     } else if ( [itemIdent isEqual:ShowFileToolbarItemIdentifier] ) {
  310:         [toolbarItem setLabel:@"Show File"];
  311:         [toolbarItem setPaletteLabel:@"Show File"];
  312:         [toolbarItem setToolTip:@"Show the saved file in the Finder"];
  313:         [toolbarItem setImage:[NSImage imageNamed:@"saveShowFile"]];
  314:         [toolbarItem setTarget:self];
  315:         [toolbarItem setAction:@selector(showFile)];
  316:     } else if ( [itemIdent isEqual:OpenFileToolbarItemIdentifier] ) {
  317:         [toolbarItem setLabel:@"Open File"];
  318:         [toolbarItem setPaletteLabel:@"Open File"];
  319:         [toolbarItem setToolTip:@"Open the saved file in its default application."];
  320:         [toolbarItem setImage:[NSImage imageNamed:@"saveOpenFile"]];
  321:         [toolbarItem setTarget:self];
  322:         [toolbarItem setAction:@selector(openFile)];
  323:     } else if ( [itemIdent isEqual:LeaveOpenToolbarItemIdentifier] ) {
  324:         if ( mSaveFileDialogShouldStayOpen ) {
  325:             [toolbarItem setLabel:@"Leave Open"];
  326:             [toolbarItem setPaletteLabel:@"Toggle Close Behavior"];
  327:             [toolbarItem setToolTip:@"Window will stay open when download finishes."];
  328:             [toolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenYES"]];
  329:             [toolbarItem setTarget:self];
  330:             [toolbarItem setAction:@selector(toggleLeaveOpen)];
  331:         } else {
  332:             [toolbarItem setLabel:@"Close When Done"];
  333:             [toolbarItem setPaletteLabel:@"Toggle Close Behavior"];
  334:             [toolbarItem setToolTip:@"Window will close automatically when download finishes."];
  335:             [toolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenNO"]];
  336:             [toolbarItem setTarget:self];
  337:             [toolbarItem setAction:@selector(toggleLeaveOpen)];
  338:         }
  339:         leaveOpenToggleToolbarItem = toolbarItem; //establish reference
  340:     } else {
  341:         toolbarItem = nil;
  342:     }
  343: 
  344:     return toolbarItem;
  345: }
  346: 
  347: -(void)cancel
  348: {
  349:     NSLog(@"Request to cancel download.");
  350:     //Put logic here!
  351: }
  352: 
  353: -(void)pauseAndResumeDownload
  354: {
  355:     if ( ! mDownloadIsPaused ) {
  356:         //Do logic to pause download
  357:         mDownloadIsPaused = YES;
  358:         [pauseResumeToggleToolbarItem setLabel:@"Resume"];
  359:         [pauseResumeToggleToolbarItem setPaletteLabel:@"Resume Download"];
  360:         [pauseResumeToggleToolbarItem setToolTip:@"Resume the paused FTP download"];
  361:         [pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"saveResume"]];
  362:     } else {
  363:         //Do logic to resume download
  364:         mDownloadIsPaused = NO;
  365:         [pauseResumeToggleToolbarItem setLabel:@"Pause"];
  366:         [pauseResumeToggleToolbarItem setPaletteLabel:@"Pause Download"];
  367:         [pauseResumeToggleToolbarItem setToolTip:@"Pause this FTP file download"];
  368:         [pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"savePause"]];
  369:     }
  370: }
  371: 
  372: -(void)showFile
  373: {
  374:     NSLog(@"Request to show file.");
  375: }
  376: 
  377: -(void)openFile
  378: {
  379:     NSLog(@"Request to open file.");
  380: }
  381: 
  382: -(void)toggleLeaveOpen
  383: {
  384:     if ( ! mSaveFileDialogShouldStayOpen ) {
  385:         mSaveFileDialogShouldStayOpen = YES;
  386:         [leaveOpenToggleToolbarItem setLabel:@"Leave Open"];
  387:         [leaveOpenToggleToolbarItem setPaletteLabel:@"Toggle Close Behavior"];
  388:         [leaveOpenToggleToolbarItem setToolTip:@"Window will stay open when download finishes."];
  389:         [leaveOpenToggleToolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenYES"]];
  390:     } else {
  391:         mSaveFileDialogShouldStayOpen = NO;
  392:         [leaveOpenToggleToolbarItem setLabel:@"Close When Done"];
  393:         [leaveOpenToggleToolbarItem setPaletteLabel:@"Toggle Close Behavior"];
  394:         [leaveOpenToggleToolbarItem setToolTip:@"Window will close automatically when download finishes."];
  395:         [leaveOpenToggleToolbarItem setImage:[NSImage imageNamed:@"saveLeaveOpenNO"]];
  396:     }
  397:     
  398:     nsCOMPtr<nsIPrefBranch> prefs(do_GetService(prefContractID));
  399:     prefs->SetBoolPref("browser.download.progressDnldDialog.keepAlive", mSaveFileDialogShouldStayOpen);
  400: }
  401: 
  402: - (void)windowWillClose:(NSNotification *)notification
  403: {
  404:     [self autorelease];
  405: }
  406: 
  407: - (void)dealloc
  408: {
  409:     NS_IF_RELEASE(mDownloadListener);
  410:     [super dealloc];
  411: }
  412: 
  413: @end

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>