File:  [mozdev] / chimera / ProgressDlgController.mm
Revision 1.13: download - view: text, annotated - select for diffs - revision graph
Thu Mar 7 18:42:43 2002 UTC (17 years, 8 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Add the tri-license to all files.

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

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