Diff for /chimera/NSBrowserView.mm between versions 1.1 and 1.7

version 1.1, 2002/01/31 20:18:48 version 1.7, 2002/02/04 07:24:35
Line 36 Line 36
  * ***** END LICENSE BLOCK ***** */   * ***** END LICENSE BLOCK ***** */
   
 #import "NSBrowserView.h"  #import "NSBrowserView.h"
   #import "ProgressDlgController.h"
 #import "nsCocoaBrowserService.h"  #import "nsCocoaBrowserService.h"
   
 // Embedding includes  // Embedding includes
Line 55 Line 56
 #include "nsXPIDLString.h"  #include "nsXPIDLString.h"
 #include "nsCOMPtr.h"  #include "nsCOMPtr.h"
   
   #include "nsIWebBrowserFocus.h"
   #include "nsIDOMHTMLDocument.h"
   #include "nsIDocument.h"
   #include "nsIURL.h"
   #include "nsIWebBrowserPersist.h"
   #include "nsIProperties.h"
   #include "nsIRequest.h"
   #include "nsIChannel.h"
   #include "nsIHttpChannel.h"
   #include "nsIPref.h"
   #include "nsIMIMEService.h"
   #include "nsIMIMEInfo.h"
   #include "nsISHistory.h"
   #include "nsIHistoryEntry.h"
   #include "nsISHEntry.h"
   
   const char* persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
   const char* dirServiceContractID = "@mozilla.org/file/directory_service;1";
   
 class nsCocoaBrowserListener : public nsSupportsWeakReference,  class nsCocoaBrowserListener : public nsSupportsWeakReference,
                                public nsIInterfaceRequestor,                                 public nsIInterfaceRequestor,
Line 567  nsCocoaBrowserListener::SetContainer(id  Line 586  nsCocoaBrowserListener::SetContainer(id 
   [mContainer retain];    [mContainer retain];
 }  }
   
   // Implementation of a header sniffer class that is used when saving Web pages and images.
   class nsHeaderSniffer :  public nsIWebProgressListener
   {
   public:
       nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
                       nsIDOMDocument* aDocument, nsIInputStream* aPostData, PRBool aBypassCache,
                       NSView* aFilterView, NSPopUpButton* aFilterList)
       {
           NS_INIT_REFCNT();
           mPersist = aPersist;
           mTmpFile = aFile;
           mURL = aURL;
           mDocument = aDocument;
           mPostData = aPostData;
           mBypassCache = aBypassCache;
           mFilterView = aFilterView;
           mFilterList = aFilterList;
       }
                     
       virtual ~nsHeaderSniffer() 
       {
       };
   
       NS_DECL_ISUPPORTS
       NS_DECL_NSIWEBPROGRESSLISTENER
     
   protected:
       void PerformSave();
       
   private:
       nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
       nsCOMPtr<nsIFile> mTmpFile;
       nsCOMPtr<nsIURI> mURL;
       nsCOMPtr<nsIDOMDocument> mDocument;
       nsCOMPtr<nsIInputStream> mPostData;
       PRBool mBypassCache;
       nsCString mContentType;
       nsCString mContentDisposition;
       NSView* mFilterView;
       NSPopUpButton* mFilterList;
   };
   
   NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
   
   // Implementation of nsIWebProgressListener
   /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
   NS_IMETHODIMP 
   nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, 
                                         nsIRequest *aRequest, 
                                         PRInt32 aStateFlags, 
                                         PRUint32 aStatus)
   {
       if (aStateFlags & nsIWebProgressListener::STATE_START) {
           nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
           nsXPIDLCString contentType;
           channel->GetContentType(getter_Copies(contentType));
           mContentType = contentType;
           
           // Get the content-disposition if we're an HTTP channel.
           nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
           if (httpChannel) {
               nsXPIDLCString disp;
               httpChannel->GetResponseHeader("content-disposition", getter_Copies(disp));
               mContentDisposition = disp;
           }
           
           mPersist->CancelSave();
           PRBool exists;
           mTmpFile->Exists(&exists);
           if (exists)
               mTmpFile->Remove(PR_FALSE);
           PerformSave();
       }
       return NS_OK;
   }
   
   void nsHeaderSniffer::PerformSave()
   {
       // Are we an HTML document? If so, we will want to append an accessory view to
       // the save dialog to provide the user with the option of doing a complete
       // save vs. a single file save.
       PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
                        mContentType.Equals("text/xml") ||
                        mContentType.Equals("application/xhtml+xml"));
       
       // Next find out the directory that we should start in.
       nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1"));
       if (!prefs)
           return;
       nsCOMPtr<nsIPrefBranch> dirBranch;
       prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
       PRInt32 filterIndex = 0;
       if (dirBranch) {
           nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
           if (NS_FAILED(rv))
               filterIndex = 0;
       }
       if (mFilterList)
           [mFilterList selectItemAtIndex: filterIndex];
           
       // We need to figure out what file name to use.
       nsCAutoString defaultFileName;
       
       if (!mContentDisposition.IsEmpty()) {
           // (1) Use the HTTP header suggestion.
           PRInt32 index = mContentDisposition.Find("filename=");
           if (index >= 0) {
               // Take the substring following the prefix.
               index += 9;
               nsCAutoString filename;
               mContentDisposition.Right(filename, mContentDisposition.Length() - index);
               defaultFileName = filename;
           }
       }
       
       if (defaultFileName.IsEmpty()) {
           nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
           if (url) {
               nsXPIDLCString fileName;
               url->GetFileName(getter_Copies(fileName));
               defaultFileName = fileName; // (2) For file URLs, use the file name.
           }
       }
       
       if (defaultFileName.IsEmpty() && mDocument && isHTML) {
           nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
           nsAutoString title;
           if (htmlDoc)
               htmlDoc->GetTitle(title); // (3) Use the title of the document.
           defaultFileName.AssignWithConversion(title);
       }
       
       if (defaultFileName.IsEmpty()) {
           // (4) Use the caller provided name. XXXdwh
       }
   
       if (defaultFileName.IsEmpty()) {
           // (5) Use the host.
           nsXPIDLCString host;
           mURL->GetHost(getter_Copies(host));
           defaultFileName = host;
       }
       
       // One last case to handle about:blank and other fruity untitled pages.
       if (defaultFileName.IsEmpty())
           defaultFileName = "untitled";
           
       // Validate the file name to ensure legality.
       for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
           if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
               defaultFileName.SetCharAt(i, ' ');
               
       // Make sure the appropriate extension is appended to the suggested file name.
       nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
       nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI));
       if (!fileURL)
           return;
       fileURL->SetFilePath(defaultFileName.get());
       
       nsXPIDLCString fileEx;
       fileURL->GetFileExtension(getter_Copies(fileEx));
       nsDependentCString fileExtension(fileEx.get());
       
       PRBool setExtension = PR_FALSE;
       if (mContentType.Equals("text/html")) {
           if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
               defaultFileName += ".html";
               setExtension = PR_TRUE;
           }
       }
       
       if (!setExtension && fileExtension.IsEmpty()) {
           nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
           if (!mimeService)
               return;
           nsCOMPtr<nsIMIMEInfo> mimeInfo;
           mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
           
           PRUint32 extCount;
           char** extList;
           mimeInfo->GetFileExtensions(&extCount, &extList);
           
           if (extCount > 0) {
               defaultFileName += ".";
               defaultFileName += extList[0];
           }
       }
       
       // Now it's time to pose the save dialog.
       NSSavePanel* savePanel = [NSSavePanel savePanel];
       NSString* file = nil;
       if (!defaultFileName.IsEmpty())
           file = [[NSString alloc] initWithCString: defaultFileName.get()];
           
       if (isHTML)
           [savePanel setAccessoryView: mFilterView];
           
       if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
           return;
          
       // Release the file string.
       [file release];
       
       // Update the filter index.
       if (isHTML && mFilterList) {
           filterIndex = [mFilterList indexOfSelectedItem];
           dirBranch->SetIntPref("save_converter_index", filterIndex);
       }
       
       // Convert the content type to text/plain if it was selected in the filter.
       if (isHTML && filterIndex == 2)
           mContentType = "text/plain";
       
       nsCOMPtr<nsISupports> sourceData;
       if (isHTML && filterIndex != 1)
           sourceData = do_QueryInterface(mDocument);
       else
           sourceData = do_QueryInterface(mURL);
           
       nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
       ProgressDlgController* progressDialog = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
       [progressDialog setWebPersist: webPersist 
                       source: sourceData.get()
                       destination: [savePanel filename]
                       contentType: mContentType.get()
                       postData: mPostData
                       bypassCache: mBypassCache];
                       
       [progressDialog showWindow: progressDialog];
   }
   
   /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
   NS_IMETHODIMP 
   nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress, 
                                            nsIRequest *aRequest, 
                                            PRInt32 aCurSelfProgress, 
                                            PRInt32 aMaxSelfProgress, 
                                            PRInt32 aCurTotalProgress, 
                                            PRInt32 aMaxTotalProgress)
   {
     return NS_OK;
   }
   
   /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
   NS_IMETHODIMP 
   nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress, 
                                            nsIRequest *aRequest, 
                                            nsIURI *location)
   {
     return NS_OK;
   }
   
   /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
   NS_IMETHODIMP 
   nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress, 
                                          nsIRequest *aRequest, 
                                          nsresult aStatus, 
                                          const PRUnichar *aMessage)
   {
     return NS_OK;
   }
   
   /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */
   NS_IMETHODIMP 
   nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, 
                                                         nsIRequest *aRequest, 
                                     PRInt32 state)
   {
     return NS_OK;
   }
   
   
 @implementation NSBrowserView  @implementation NSBrowserView
   
Line 608  nsCocoaBrowserListener::SetContainer(id  Line 898  nsCocoaBrowserListener::SetContainer(id 
   return self;    return self;
 }  }
   
   - (void)destroyWebBrowser
   {
     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
     baseWin->Destroy();
   }
   
 - (void)dealloc   - (void)dealloc 
 {  {
   NS_RELEASE(_listener);    NS_RELEASE(_listener);
Line 805  nsCocoaBrowserListener::SetContainer(id  Line 1101  nsCocoaBrowserListener::SetContainer(id 
   
 }  }
   
   -(void) saveInternal: (nsIURI*)aURI
           withDocument: (nsIDOMDocument*)aDocument
           bypassCache: (BOOL)aBypassCache
           filterView: (NSView*)aFilterView
           filterList: (NSPopUpButton*)aFilterList
   {
       // Create our web browser persist object.  This is the object that knows
       // how to actually perform the saving of the page (and of the images
       // on the page).
       nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
       if (!webPersist)
           return;
       
       // Make a temporary file object that we can save to.
       nsCOMPtr<nsIProperties> dirService(do_GetService(dirServiceContractID));
       if (!dirService)
           return;
       nsCOMPtr<nsIFile> tmpFile;
       dirService->Get("TmpD", NS_GET_IID(nsIFile), getter_AddRefs(tmpFile));
       static short unsigned int tmpRandom = 0;
       nsCAutoString tmpNo; tmpNo.AssignWithConversion(tmpRandom++);
       nsCAutoString saveFile("-sav");
       saveFile += tmpNo;
       saveFile += "tmp";
       tmpFile->Append(saveFile.get()); 
       
       // Get the post data if we're an HTML doc.
       nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(_webBrowser));
       nsCOMPtr<nsISHistory> sessionHistory;
       webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
       nsCOMPtr<nsIHistoryEntry> entry;
       PRInt32 sindex;
       sessionHistory->GetIndex(&sindex);
       sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
       nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
       nsCOMPtr<nsIInputStream> postData;
       if (shEntry)
           shEntry->GetPostData(getter_AddRefs(postData));
       
       nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI, 
                                                      aDocument, postData, aBypassCache,
                                                      aFilterView, aFilterList);
       if (!sniffer)
           return;
       webPersist->SetProgressListener(sniffer);
       webPersist->SaveURI(aURI, nsnull, tmpFile);
   }
   
   -(void)saveDocument: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
   {
       nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
       nsCOMPtr<nsIDOMWindow> domWindow;
       wbf->GetFocusedWindow(getter_AddRefs(domWindow));
       if (!domWindow)
           _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
       if (!domWindow)
           return;
       
       nsCOMPtr<nsIDOMDocument> domDocument;
       domWindow->GetDocument(getter_AddRefs(domDocument));
       if (!domDocument)
           return;
       nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDocument));
       if (!doc)
           return;
       nsCOMPtr<nsIURI> url;
       doc->GetDocumentURL(getter_AddRefs(url));
        
       [self saveInternal: url.get()
             withDocument: domDocument
             bypassCache: NO
             filterView: aFilterView
             filterList: aFilterList];
   }
   
 @end  @end
   

Removed from v.1.1  
changed lines
  Added in v.1.7


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