File:  [mozdev] / chimera / NSBrowserView.mm
Revision 1.16: download - view: text, annotated - select for diffs - revision graph
Tue Feb 5 10:16:31 2002 UTC (17 years, 9 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
More find dialog work.

    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) 1998
   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 "NSBrowserView.h"
   39: #import "ProgressDlgController.h"
   40: #import "FindDlgController.h"
   41: #import "nsCocoaBrowserService.h"
   42: 
   43: // Embedding includes
   44: #include "nsCWebBrowser.h"
   45: #include "nsIInterfaceRequestor.h"
   46: #include "nsIWebBrowserChrome.h"
   47: #include "nsIEmbeddingSiteWindow.h"
   48: #include "nsIWebProgressListener.h"
   49: #include "nsIWebBrowser.h"
   50: #include "nsIWebNavigation.h"
   51: #include "nsIURI.h"
   52: #include "nsIDOMWindow.h"
   53: #include "nsWeakReference.h"
   54: 
   55: // XPCOM and String includes
   56: #include "nsCRT.h"
   57: #include "nsXPIDLString.h"
   58: #include "nsCOMPtr.h"
   59: 
   60: // Printing
   61: #include "nsIWebBrowserPrint.h"
   62: #include "nsIPrintSettings.h"
   63: 
   64: // Saving of links/images/docs
   65: #include "nsIWebBrowserFocus.h"
   66: #include "nsIDOMHTMLDocument.h"
   67: #include "nsIDocument.h"
   68: #include "nsIURL.h"
   69: #include "nsIWebBrowserPersist.h"
   70: #include "nsIProperties.h"
   71: #include "nsIRequest.h"
   72: #include "nsIChannel.h"
   73: #include "nsIHttpChannel.h"
   74: #include "nsIPref.h"
   75: #include "nsIMIMEService.h"
   76: #include "nsIMIMEInfo.h"
   77: #include "nsISHistory.h"
   78: #include "nsIHistoryEntry.h"
   79: #include "nsISHEntry.h"
   80: 
   81: // Cut/copy/paste
   82: #include "nsIClipboardCommands.h"
   83: #include "nsIInterfaceRequestorUtils.h"
   84: 
   85: const char* persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
   86: const char* dirServiceContractID = "@mozilla.org/file/directory_service;1";
   87: 
   88: class nsCocoaBrowserListener : public nsSupportsWeakReference,
   89:                                public nsIInterfaceRequestor,
   90: 			       public nsIWebBrowserChrome,
   91: 			       public nsIEmbeddingSiteWindow,
   92:                                public nsIWebProgressListener
   93: {
   94: public:
   95:   nsCocoaBrowserListener(NSBrowserView* aView);
   96:   virtual ~nsCocoaBrowserListener();
   97: 
   98:   NS_DECL_ISUPPORTS
   99:   NS_DECL_NSIINTERFACEREQUESTOR
  100:   NS_DECL_NSIWEBBROWSERCHROME
  101:   NS_DECL_NSIEMBEDDINGSITEWINDOW
  102:   NS_DECL_NSIWEBPROGRESSLISTENER
  103: 
  104:   void AddListener(id <NSBrowserListener> aListener);
  105:   void RemoveListener(id <NSBrowserListener> aListener);
  106:   void SetContainer(id <NSBrowserContainer> aContainer);
  107: 
  108: private:
  109:   NSBrowserView* mView;     // WEAK - it owns us
  110:   NSMutableArray* mListeners;
  111:   id <NSBrowserContainer> mContainer;
  112:   PRBool mIsModal;
  113:   PRUint32 mChromeFlags;
  114: };
  115: 
  116: nsCocoaBrowserListener::nsCocoaBrowserListener(NSBrowserView* aView)
  117:   : mView(aView), mContainer(nsnull), mIsModal(PR_FALSE), mChromeFlags(0)
  118: {
  119:   NS_INIT_ISUPPORTS();
  120:   mListeners = [[NSMutableArray alloc] init];
  121: }
  122: 
  123: nsCocoaBrowserListener::~nsCocoaBrowserListener()
  124: {
  125:   [mListeners release];
  126:   mView = nsnull;
  127:   if (mContainer) {
  128:     [mContainer release];
  129:   }
  130: }
  131: 
  132: NS_IMPL_ISUPPORTS5(nsCocoaBrowserListener,
  133: 		   nsIInterfaceRequestor,
  134: 		   nsIWebBrowserChrome,
  135: 		   nsIEmbeddingSiteWindow,
  136: 		   nsIWebProgressListener,
  137:      		   nsISupportsWeakReference)
  138: 
  139: // Implementation of nsIInterfaceRequestor
  140: NS_IMETHODIMP 
  141: nsCocoaBrowserListener::GetInterface(const nsIID &aIID, void** aInstancePtr)
  142: {
  143:   if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) {
  144:     nsCOMPtr<nsIWebBrowser> browser = dont_AddRef([mView getWebBrowser]);
  145:     if (browser)
  146:       return browser->GetContentDOMWindow((nsIDOMWindow **) aInstancePtr);
  147:   }
  148:   
  149:   return QueryInterface(aIID, aInstancePtr);
  150: }
  151: 
  152: // Implementation of nsIWebBrowserChrome
  153: /* void setStatus (in unsigned long statusType, in wstring status); */
  154: NS_IMETHODIMP 
  155: nsCocoaBrowserListener::SetStatus(PRUint32 statusType, const PRUnichar *status)
  156: {
  157:   if (!mContainer) {
  158:     return NS_ERROR_FAILURE;
  159:   }
  160: 
  161:   NSString* str = nsnull;
  162:   if (status && (*status != PRUnichar(0))) {
  163:     str = [NSString stringWithCharacters:status length:nsCRT::strlen(status)];
  164:   }
  165: 
  166:   [mContainer setStatus:str ofType:(NSStatusType)statusType];
  167: 
  168:   return NS_OK;
  169: }
  170: 
  171: /* attribute nsIWebBrowser webBrowser; */
  172: NS_IMETHODIMP 
  173: nsCocoaBrowserListener::GetWebBrowser(nsIWebBrowser * *aWebBrowser)
  174: {
  175:   NS_ENSURE_ARG_POINTER(aWebBrowser);
  176:   if (!mView) {
  177:     return NS_ERROR_FAILURE;
  178:   }
  179:   *aWebBrowser = [mView getWebBrowser];
  180: 
  181:   return NS_OK;
  182: }
  183: NS_IMETHODIMP 
  184: nsCocoaBrowserListener::SetWebBrowser(nsIWebBrowser * aWebBrowser)
  185: {
  186:   if (!mView) {
  187:     return NS_ERROR_FAILURE;
  188:   }
  189: 
  190:   [mView setWebBrowser:aWebBrowser];
  191: 
  192:   return NS_OK;
  193: }
  194: 
  195: /* attribute unsigned long chromeFlags; */
  196: NS_IMETHODIMP 
  197: nsCocoaBrowserListener::GetChromeFlags(PRUint32 *aChromeFlags)
  198: {
  199:   NS_ENSURE_ARG_POINTER(aChromeFlags);
  200:   *aChromeFlags = mChromeFlags;
  201:   return NS_OK;
  202: }
  203: NS_IMETHODIMP 
  204: nsCocoaBrowserListener::SetChromeFlags(PRUint32 aChromeFlags)
  205: {
  206:   // XXX Do nothing with them for now
  207:   mChromeFlags = aChromeFlags;
  208:   return NS_OK;
  209: }
  210: 
  211: /* void destroyBrowserWindow (); */
  212: NS_IMETHODIMP 
  213: nsCocoaBrowserListener::DestroyBrowserWindow()
  214: {
  215:   // XXX Could send this up to the container, but for now,
  216:   // we just destroy the enclosing window.
  217:   NSWindow* window = [mView window];
  218: 
  219:   if (window) {
  220:     [window close];
  221:   }
  222: 
  223:   return NS_OK;
  224: }
  225: 
  226: /* void sizeBrowserTo (in long aCX, in long aCY); */
  227: NS_IMETHODIMP 
  228: nsCocoaBrowserListener::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
  229: {
  230:   if (mContainer) {
  231:     NSSize size;
  232:     
  233:     size.width = (float)aCX;
  234:     size.height = (float)aCY;
  235: 
  236:     [mContainer sizeBrowserTo:size];
  237:   }
  238:   
  239:   return NS_OK;
  240: }
  241: 
  242: /* void showAsModal (); */
  243: NS_IMETHODIMP 
  244: nsCocoaBrowserListener::ShowAsModal()
  245: {
  246:   if (!mView) {
  247:     return NS_ERROR_FAILURE;
  248:   }
  249: 
  250:   NSWindow* window = [mView window];
  251: 
  252:   if (!window) {
  253:     return NS_ERROR_FAILURE;
  254:   }
  255: 
  256:   mIsModal = PR_TRUE;
  257:   int result = [NSApp runModalForWindow:window];
  258:   mIsModal = PR_FALSE;
  259: 
  260:   return (nsresult)result;
  261: }
  262: 
  263: /* boolean isWindowModal (); */
  264: NS_IMETHODIMP 
  265: nsCocoaBrowserListener::IsWindowModal(PRBool *_retval)
  266: {
  267:   NS_ENSURE_ARG_POINTER(_retval);
  268: 
  269:   *_retval = mIsModal;
  270: 
  271:   return NS_OK;
  272: }
  273: 
  274: /* void exitModalEventLoop (in nsresult aStatus); */
  275: NS_IMETHODIMP 
  276: nsCocoaBrowserListener::ExitModalEventLoop(nsresult aStatus)
  277: {
  278:   [NSApp stopModalWithCode:(int)aStatus];
  279: 
  280:   return NS_OK;
  281: }
  282: 
  283: // Implementation of nsIEmbeddingSiteWindow
  284: /* void setDimensions (in unsigned long flags, in long x, in long y, in long cx, in long cy); */
  285: NS_IMETHODIMP 
  286: nsCocoaBrowserListener::SetDimensions(PRUint32 flags, 
  287: 				      PRInt32 x, 
  288: 				      PRInt32 y, 
  289: 				      PRInt32 cx, 
  290: 				      PRInt32 cy)
  291: {
  292:   if (!mView) {
  293:     return NS_ERROR_FAILURE;
  294:   }
  295: 
  296:   NSWindow* window = [mView window];
  297:   if (!window) {
  298:     return NS_ERROR_FAILURE;
  299:   }
  300: 
  301:   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) {
  302:     NSPoint origin;
  303:     origin.x = (float)x;
  304:     origin.y = (float)y;
  305:     [window setFrameOrigin:origin];
  306:   }
  307: 
  308:   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
  309:     NSRect frame = [window frame];
  310:     frame.size.width = (float)cx;
  311:     frame.size.height = (float)cy;
  312:     [window setFrame:frame display:YES];
  313:   }
  314:   else if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER) {
  315:     NSSize size;
  316:     size.width = (float)cx;
  317:     size.height = (float)cy;
  318:     [window setContentSize:size];
  319:   }
  320: 
  321:   return NS_OK;
  322: }
  323: 
  324: /* void getDimensions (in unsigned long flags, out long x, out long y, out long cx, out long cy); */
  325: NS_IMETHODIMP 
  326: nsCocoaBrowserListener::GetDimensions(PRUint32 flags, 
  327: 				      PRInt32 *x, 
  328: 				      PRInt32 *y, 
  329: 				      PRInt32 *cx, 
  330: 				      PRInt32 *cy)
  331: {
  332:   NS_ENSURE_ARG_POINTER(x);
  333:   NS_ENSURE_ARG_POINTER(y);
  334:   NS_ENSURE_ARG_POINTER(cx);
  335:   NS_ENSURE_ARG_POINTER(cy);
  336: 
  337:   if (!mView) {
  338:     return NS_ERROR_FAILURE;
  339:   }
  340: 
  341:   NSWindow* window = [mView window];
  342:   if (!window) {
  343:     return NS_ERROR_FAILURE;
  344:   }
  345: 
  346:   NSRect frame = [window frame];
  347:   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) {
  348:     *x = (PRInt32)frame.origin.x;
  349:     *y = (PRInt32)frame.origin.y;
  350:   }
  351:   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
  352:     *cx = (PRInt32)frame.size.width;
  353:     *cy = (PRInt32)frame.size.height;
  354:   }
  355:   else if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER) {
  356:     NSView* contentView = [window contentView];
  357:     NSRect contentFrame = [contentView frame];
  358:     *cx = (PRInt32)contentFrame.size.width;
  359:     *cy = (PRInt32)contentFrame.size.height;    
  360:   }
  361: 
  362:   return NS_OK;
  363: }
  364: 
  365: /* void setFocus (); */
  366: NS_IMETHODIMP 
  367: nsCocoaBrowserListener::SetFocus()
  368: {
  369:   if (!mView) {
  370:     return NS_ERROR_FAILURE;
  371:   }
  372: 
  373:   NSWindow* window = [mView window];
  374:   if (!window) {
  375:     return NS_ERROR_FAILURE;
  376:   }
  377: 
  378:   [window makeKeyAndOrderFront:window];
  379: 
  380:   return NS_OK;
  381: }
  382: 
  383: /* attribute boolean visibility; */
  384: NS_IMETHODIMP 
  385: nsCocoaBrowserListener::GetVisibility(PRBool *aVisibility)
  386: {
  387:   NS_ENSURE_ARG_POINTER(aVisibility);
  388: 
  389:   if (!mView) {
  390:     return NS_ERROR_FAILURE;
  391:   }
  392: 
  393:   NSWindow* window = [mView window];
  394:   if (!window) {
  395:     return NS_ERROR_FAILURE;
  396:   }
  397: 
  398:   *aVisibility = [window isMiniaturized];
  399: 
  400:   return NS_OK;
  401: }
  402: NS_IMETHODIMP 
  403: nsCocoaBrowserListener::SetVisibility(PRBool aVisibility)
  404: {
  405:   if (!mView) {
  406:     return NS_ERROR_FAILURE;
  407:   }
  408: 
  409:   NSWindow* window = [mView window];
  410:   if (!window) {
  411:     return NS_ERROR_FAILURE;
  412:   }
  413: 
  414:   if (aVisibility) {
  415:     [window deminiaturize:window];
  416:   }
  417:   else {
  418:     [window miniaturize:window];
  419:   }
  420: 
  421:   return NS_OK;
  422: }
  423: 
  424: /* attribute wstring title; */
  425: NS_IMETHODIMP 
  426: nsCocoaBrowserListener::GetTitle(PRUnichar * *aTitle)
  427: {
  428:   NS_ENSURE_ARG_POINTER(aTitle);
  429: 
  430:   if (!mContainer) {
  431:     return NS_ERROR_FAILURE;
  432:   }
  433: 
  434:   NSString* title = [mContainer title];
  435:   unsigned int length = [title length];
  436:   if (length) {
  437:     *aTitle = (PRUnichar*)nsMemory::Alloc((length+1)*sizeof(PRUnichar));
  438:     if (!*aTitle) {
  439:       return NS_ERROR_OUT_OF_MEMORY;
  440:     }
  441:     [title getCharacters:*aTitle];
  442:   }
  443:   else {
  444:     *aTitle = nsnull;
  445:   }
  446:   
  447:   return NS_OK;
  448: }
  449: NS_IMETHODIMP 
  450: nsCocoaBrowserListener::SetTitle(const PRUnichar * aTitle)
  451: {
  452:   NS_ENSURE_ARG(aTitle);
  453: 
  454:   if (!mContainer) {
  455:     return NS_ERROR_FAILURE;
  456:   }
  457: 
  458:   NSString* str = [NSString stringWithCharacters:aTitle length:nsCRT::strlen(aTitle)];
  459:   [mContainer setTitle:str];
  460: 
  461:   return NS_OK;
  462: }
  463: 
  464: /* [noscript] readonly attribute voidPtr siteWindow; */
  465: NS_IMETHODIMP 
  466: nsCocoaBrowserListener::GetSiteWindow(void * *aSiteWindow)
  467: {
  468:   NS_ENSURE_ARG_POINTER(aSiteWindow);
  469: 
  470:   if (!mView) {
  471:     return NS_ERROR_FAILURE;
  472:   }
  473: 
  474:   NSWindow* window = [mView window];
  475:   if (!window) {
  476:     return NS_ERROR_FAILURE;
  477:   }
  478: 
  479:   *aSiteWindow = (void*)window;
  480: 
  481:   return NS_OK;
  482: }
  483: 
  484: // Implementation of nsIWebProgressListener
  485: /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
  486: NS_IMETHODIMP 
  487: nsCocoaBrowserListener::OnStateChange(nsIWebProgress *aWebProgress, 
  488: 				      nsIRequest *aRequest, 
  489: 				      PRInt32 aStateFlags, 
  490: 				      PRUint32 aStatus)
  491: {
  492:   NSEnumerator* enumerator = [mListeners objectEnumerator];
  493:   id obj;
  494:   
  495:   if (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) {
  496:     if (aStateFlags & nsIWebProgressListener::STATE_START) {
  497:       while ((obj = [enumerator nextObject])) {
  498: 	[obj onLoadingStarted];
  499:       }
  500:     }
  501:     else if (aStateFlags & nsIWebProgressListener::STATE_STOP) {
  502:       while ((obj = [enumerator nextObject])) {
  503: 	[obj onLoadingCompleted:(NS_SUCCEEDED(aStatus))];
  504:       }
  505:     }
  506:   }
  507: 
  508: 
  509:   return NS_OK;
  510: }
  511: 
  512: /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
  513: NS_IMETHODIMP 
  514: nsCocoaBrowserListener::OnProgressChange(nsIWebProgress *aWebProgress, 
  515: 					 nsIRequest *aRequest, 
  516: 					 PRInt32 aCurSelfProgress, 
  517: 					 PRInt32 aMaxSelfProgress, 
  518: 					 PRInt32 aCurTotalProgress, 
  519: 					 PRInt32 aMaxTotalProgress)
  520: {
  521:   NSEnumerator* enumerator = [mListeners objectEnumerator];
  522:   id obj;
  523:  
  524:   while ((obj = [enumerator nextObject])) {
  525:     [obj onProgressChange:aCurTotalProgress outOf:aMaxTotalProgress];
  526:   }
  527:   
  528:   return NS_OK;
  529: }
  530: 
  531: /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
  532: NS_IMETHODIMP 
  533: nsCocoaBrowserListener::OnLocationChange(nsIWebProgress *aWebProgress, 
  534: 					 nsIRequest *aRequest, 
  535: 					 nsIURI *location)
  536: {
  537:   nsXPIDLCString spec;
  538:   
  539:   location->GetSpec(getter_Copies(spec));
  540:   if (!spec) {
  541:     return NS_ERROR_FAILURE;
  542:   }
  543: 
  544:   const char* cstr = spec.get();
  545:   NSString* str = [NSString stringWithCString:cstr];
  546:   NSURL* url = [NSURL URLWithString:str];
  547: 
  548:   NSEnumerator* enumerator = [mListeners objectEnumerator];
  549:   id obj;
  550:  
  551:   while ((obj = [enumerator nextObject])) {
  552:     [obj onLocationChange:url];
  553:   }
  554: 
  555:   return NS_OK;
  556: }
  557: 
  558: /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
  559: NS_IMETHODIMP 
  560: nsCocoaBrowserListener::OnStatusChange(nsIWebProgress *aWebProgress, 
  561: 				       nsIRequest *aRequest, 
  562: 				       nsresult aStatus, 
  563: 				       const PRUnichar *aMessage)
  564: {
  565:   return NS_OK;
  566: }
  567: 
  568: /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */
  569: NS_IMETHODIMP 
  570: nsCocoaBrowserListener::OnSecurityChange(nsIWebProgress *aWebProgress, 
  571: 					 nsIRequest *aRequest, 
  572: 					 PRInt32 state)
  573: {
  574:   return NS_OK;
  575: }
  576: 
  577: void 
  578: nsCocoaBrowserListener::AddListener(id <NSBrowserListener> aListener)
  579: {
  580:   [mListeners addObject:aListener];
  581: }
  582: 
  583: void 
  584: nsCocoaBrowserListener::RemoveListener(id <NSBrowserListener> aListener)
  585: {
  586:   [mListeners removeObject:aListener];
  587: }
  588: 
  589: void 
  590: nsCocoaBrowserListener::SetContainer(id <NSBrowserContainer> aContainer)
  591: {
  592:   [mContainer autorelease];
  593: 
  594:   mContainer = aContainer;
  595: 
  596:   [mContainer retain];
  597: }
  598: 
  599: // Implementation of a header sniffer class that is used when saving Web pages and images.
  600: class nsHeaderSniffer :  public nsIWebProgressListener
  601: {
  602: public:
  603:     nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
  604:                     nsIDOMDocument* aDocument, nsIInputStream* aPostData, PRBool aBypassCache,
  605:                     NSView* aFilterView, NSPopUpButton* aFilterList)
  606:     {
  607:         NS_INIT_REFCNT();
  608:         mPersist = aPersist;
  609:         mTmpFile = aFile;
  610:         mURL = aURL;
  611:         mDocument = aDocument;
  612:         mPostData = aPostData;
  613:         mBypassCache = aBypassCache;
  614:         mFilterView = aFilterView;
  615:         mFilterList = aFilterList;
  616:     }
  617:                   
  618:     virtual ~nsHeaderSniffer() 
  619:     {
  620:     };
  621: 
  622:     NS_DECL_ISUPPORTS
  623:     NS_DECL_NSIWEBPROGRESSLISTENER
  624:   
  625: protected:
  626:     void PerformSave();
  627:     
  628: private:
  629:     nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
  630:     nsCOMPtr<nsIFile> mTmpFile;
  631:     nsCOMPtr<nsIURI> mURL;
  632:     nsCOMPtr<nsIDOMDocument> mDocument;
  633:     nsCOMPtr<nsIInputStream> mPostData;
  634:     PRBool mBypassCache;
  635:     nsCString mContentType;
  636:     nsCString mContentDisposition;
  637:     NSView* mFilterView;
  638:     NSPopUpButton* mFilterList;
  639: };
  640: 
  641: NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
  642: 
  643: // Implementation of nsIWebProgressListener
  644: /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
  645: NS_IMETHODIMP 
  646: nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, 
  647: 				      nsIRequest *aRequest, 
  648: 				      PRInt32 aStateFlags, 
  649: 				      PRUint32 aStatus)
  650: {
  651:     if (aStateFlags & nsIWebProgressListener::STATE_START) {
  652:         nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
  653:         nsXPIDLCString contentType;
  654:         channel->GetContentType(getter_Copies(contentType));
  655:         mContentType = contentType;
  656:         
  657:         // Get the content-disposition if we're an HTTP channel.
  658:         nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
  659:         if (httpChannel) {
  660:             nsXPIDLCString disp;
  661:             httpChannel->GetResponseHeader("content-disposition", getter_Copies(disp));
  662:             mContentDisposition = disp;
  663:         }
  664:         
  665:         mPersist->CancelSave();
  666:         PRBool exists;
  667:         mTmpFile->Exists(&exists);
  668:         if (exists)
  669:             mTmpFile->Remove(PR_FALSE);
  670:         PerformSave();
  671:     }
  672:     return NS_OK;
  673: }
  674: 
  675: void nsHeaderSniffer::PerformSave()
  676: {
  677:     // Are we an HTML document? If so, we will want to append an accessory view to
  678:     // the save dialog to provide the user with the option of doing a complete
  679:     // save vs. a single file save.
  680:     PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
  681:                      mContentType.Equals("text/xml") ||
  682:                      mContentType.Equals("application/xhtml+xml"));
  683:     
  684:     // Next find out the directory that we should start in.
  685:     nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1"));
  686:     if (!prefs)
  687:         return;
  688:     nsCOMPtr<nsIPrefBranch> dirBranch;
  689:     prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
  690:     PRInt32 filterIndex = 0;
  691:     if (dirBranch) {
  692:         nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
  693:         if (NS_FAILED(rv))
  694:             filterIndex = 0;
  695:     }
  696:     if (mFilterList)
  697:         [mFilterList selectItemAtIndex: filterIndex];
  698:         
  699:     // We need to figure out what file name to use.
  700:     nsCAutoString defaultFileName;
  701:     
  702:     if (!mContentDisposition.IsEmpty()) {
  703:         // (1) Use the HTTP header suggestion.
  704:         PRInt32 index = mContentDisposition.Find("filename=");
  705:         if (index >= 0) {
  706:             // Take the substring following the prefix.
  707:             index += 9;
  708:             nsCAutoString filename;
  709:             mContentDisposition.Right(filename, mContentDisposition.Length() - index);
  710:             defaultFileName = filename;
  711:         }
  712:     }
  713:     
  714:     if (defaultFileName.IsEmpty()) {
  715:         nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
  716:         if (url) {
  717:             nsXPIDLCString fileName;
  718:             url->GetFileName(getter_Copies(fileName));
  719:             defaultFileName = fileName; // (2) For file URLs, use the file name.
  720:         }
  721:     }
  722:     
  723:     if (defaultFileName.IsEmpty() && mDocument && isHTML) {
  724:         nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
  725:         nsAutoString title;
  726:         if (htmlDoc)
  727:             htmlDoc->GetTitle(title); // (3) Use the title of the document.
  728:         defaultFileName.AssignWithConversion(title);
  729:     }
  730:     
  731:     if (defaultFileName.IsEmpty()) {
  732:         // (4) Use the caller provided name. XXXdwh
  733:     }
  734: 
  735:     if (defaultFileName.IsEmpty()) {
  736:         // (5) Use the host.
  737:         nsXPIDLCString host;
  738:         mURL->GetHost(getter_Copies(host));
  739:         defaultFileName = host;
  740:     }
  741:     
  742:     // One last case to handle about:blank and other fruity untitled pages.
  743:     if (defaultFileName.IsEmpty())
  744:         defaultFileName = "untitled";
  745:         
  746:     // Validate the file name to ensure legality.
  747:     for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
  748:         if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
  749:             defaultFileName.SetCharAt(i, ' ');
  750:             
  751:     // Make sure the appropriate extension is appended to the suggested file name.
  752:     nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
  753:     nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI));
  754:     if (!fileURL)
  755:         return;
  756:     fileURL->SetFilePath(defaultFileName.get());
  757:     
  758:     nsXPIDLCString fileEx;
  759:     fileURL->GetFileExtension(getter_Copies(fileEx));
  760:     nsDependentCString fileExtension(fileEx.get());
  761:     
  762:     PRBool setExtension = PR_FALSE;
  763:     if (mContentType.Equals("text/html")) {
  764:         if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
  765:             defaultFileName += ".html";
  766:             setExtension = PR_TRUE;
  767:         }
  768:     }
  769:     
  770:     if (!setExtension && fileExtension.IsEmpty()) {
  771:         nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
  772:         if (!mimeService)
  773:             return;
  774:         nsCOMPtr<nsIMIMEInfo> mimeInfo;
  775:         mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
  776:         
  777:         PRUint32 extCount;
  778:         char** extList;
  779:         mimeInfo->GetFileExtensions(&extCount, &extList);
  780:         
  781:         if (extCount > 0) {
  782:             defaultFileName += ".";
  783:             defaultFileName += extList[0];
  784:         }
  785:     }
  786:     
  787:     // Now it's time to pose the save dialog.
  788:     NSSavePanel* savePanel = [NSSavePanel savePanel];
  789:     NSString* file = nil;
  790:     if (!defaultFileName.IsEmpty())
  791:         file = [[NSString alloc] initWithCString: defaultFileName.get()];
  792:         
  793:     if (isHTML)
  794:         [savePanel setAccessoryView: mFilterView];
  795:         
  796:     if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
  797:         return;
  798:        
  799:     // Release the file string.
  800:     [file release];
  801:     
  802:     // Update the filter index.
  803:     if (isHTML && mFilterList) {
  804:         filterIndex = [mFilterList indexOfSelectedItem];
  805:         dirBranch->SetIntPref("save_converter_index", filterIndex);
  806:     }
  807:     
  808:     // Convert the content type to text/plain if it was selected in the filter.
  809:     if (isHTML && filterIndex == 2)
  810:         mContentType = "text/plain";
  811:     
  812:     nsCOMPtr<nsISupports> sourceData;
  813:     if (isHTML && filterIndex != 1)
  814:         sourceData = do_QueryInterface(mDocument);
  815:     else
  816:         sourceData = do_QueryInterface(mURL);
  817:         
  818:     nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
  819:     ProgressDlgController* progressDialog = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
  820:     [progressDialog setWebPersist: webPersist 
  821:                     source: sourceData.get()
  822:                     destination: [savePanel filename]
  823:                     contentType: mContentType.get()
  824:                     postData: mPostData
  825:                     bypassCache: mBypassCache];
  826:                     
  827:     [progressDialog showWindow: progressDialog];
  828: }
  829: 
  830: /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
  831: NS_IMETHODIMP 
  832: nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress, 
  833: 					 nsIRequest *aRequest, 
  834: 					 PRInt32 aCurSelfProgress, 
  835: 					 PRInt32 aMaxSelfProgress, 
  836: 					 PRInt32 aCurTotalProgress, 
  837: 					 PRInt32 aMaxTotalProgress)
  838: {
  839:   return NS_OK;
  840: }
  841: 
  842: /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
  843: NS_IMETHODIMP 
  844: nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress, 
  845: 					 nsIRequest *aRequest, 
  846: 					 nsIURI *location)
  847: {
  848:   return NS_OK;
  849: }
  850: 
  851: /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
  852: NS_IMETHODIMP 
  853: nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress, 
  854: 				       nsIRequest *aRequest, 
  855: 				       nsresult aStatus, 
  856: 				       const PRUnichar *aMessage)
  857: {
  858:   return NS_OK;
  859: }
  860: 
  861: /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */
  862: NS_IMETHODIMP 
  863: nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, 
  864: 					              nsIRequest *aRequest, 
  865:                                   PRInt32 state)
  866: {
  867:   return NS_OK;
  868: }
  869: 
  870: 
  871: @implementation NSBrowserView
  872: 
  873: - (id)initWithFrame:(NSRect)frame
  874: {
  875:   [super initWithFrame:frame];
  876: 
  877:   nsresult rv = nsCocoaBrowserService::InitEmbedding();
  878:   if (NS_FAILED(rv)) {
  879:     // XXX need to throw
  880:   }
  881:   
  882:   _listener = new nsCocoaBrowserListener(self);
  883:   NS_ADDREF(_listener);
  884: 
  885:   // Create the web browser instance
  886:   nsCOMPtr<nsIWebBrowser> browser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
  887:   if (NS_FAILED(rv)) {
  888:     // XXX need to throw
  889:   }
  890: 
  891:   _webBrowser = browser;
  892:   NS_ADDREF(_webBrowser);
  893: 
  894:   // Set the container nsIWebBrowserChrome
  895:   _webBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome *, 
  896: 						 _listener));
  897:   
  898:   // Register as a listener for web progress
  899:   nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(NS_STATIC_CAST(nsIWebProgressListener*, _listener));
  900:   _webBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
  901: 
  902:   // Hook up the widget hierarchy with us as the parent
  903:   nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
  904:   baseWin->InitWindow((NSView*)self, nsnull, 0, 0, 
  905: 		      frame.size.width, frame.size.height);
  906:   baseWin->Create();
  907: 
  908:   return self;
  909: }
  910: 
  911: - (void)destroyWebBrowser
  912: {
  913:   nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
  914:   baseWin->Destroy();
  915: }
  916: 
  917: - (void)dealloc 
  918: {
  919:   NS_RELEASE(_listener);
  920:   NS_IF_RELEASE(_webBrowser);
  921:   
  922:   nsCocoaBrowserService::BrowserClosed();
  923:   
  924:   [super dealloc];
  925: }
  926: 
  927: - (void)setFrame:(NSRect)frameRect 
  928: {
  929:   [super setFrame:frameRect];
  930:   if (_webBrowser) {
  931:     nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(_webBrowser);
  932:     window->SetSize((PRInt32)frameRect.size.width, 
  933: 		    (PRInt32)frameRect.size.height,
  934: 		    PR_TRUE);
  935:   }
  936: }
  937: 
  938: - (void)addListener:(id <NSBrowserListener>)listener
  939: {
  940:   _listener->AddListener(listener);
  941: }
  942: 
  943: - (void)removeListener:(id <NSBrowserListener>)listener
  944: {
  945:   _listener->RemoveListener(listener);
  946: }
  947: 
  948: - (void)setContainer:(id <NSBrowserContainer>)container
  949: {
  950:   _listener->SetContainer(container);
  951: }
  952: 
  953: - (nsIDOMWindow*)getContentWindow
  954: {
  955:   nsIDOMWindow* window;
  956: 
  957:   _webBrowser->GetContentDOMWindow(&window);
  958: 
  959:   return window;
  960: }
  961: 
  962: - (void)loadURI:(NSURL *)url flags:(unsigned int)flags
  963: {
  964:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
  965:   
  966:   NSString* spec = [url absoluteString];
  967:   int length = [spec length];
  968:   PRUnichar* specStr = nsMemory::Alloc((length+1) * sizeof(PRUnichar));
  969:   [spec getCharacters:specStr];
  970:   specStr[length] = PRUnichar(0);
  971:   
  972: 
  973:   PRUint32 navFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
  974:   if (flags & NSLoadFlagsDontPutInHistory) {
  975:     navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_HISTORY;
  976:   }
  977:   if (flags & NSLoadFlagsReplaceHistoryEntry) {
  978:     navFlags |= nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY;
  979:   }
  980:   if (flags & NSLoadFlagsBypassCacheAndProxy) {
  981:     navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | 
  982:                 nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
  983:   }
  984: 
  985:   nsresult rv = nav->LoadURI(specStr, navFlags, nsnull, nsnull, nsnull);
  986:   if (NS_FAILED(rv)) {
  987:     // XXX need to throw
  988:   }
  989: 
  990:   nsMemory::Free(specStr);
  991: }
  992: 
  993: - (void)reload:(unsigned int)flags
  994: {
  995:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
  996: 
  997:   PRUint32 navFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
  998:   if (flags & NSLoadFlagsBypassCacheAndProxy) {
  999:     navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | 
 1000:                 nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
 1001:   }
 1002: 
 1003:   nsresult rv = nav->Reload(navFlags);
 1004:   if (NS_FAILED(rv)) {
 1005:     // XXX need to throw
 1006:   }  
 1007: }
 1008: 
 1009: - (BOOL)canGoBack
 1010: {
 1011:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 1012: 
 1013:   PRBool can;
 1014:   nav->GetCanGoBack(&can);
 1015: 
 1016:   return can ? YES : NO;
 1017: }
 1018: 
 1019: - (BOOL)canGoForward
 1020: {
 1021:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 1022: 
 1023:   PRBool can;
 1024:   nav->GetCanGoForward(&can);
 1025: 
 1026:   return can ? YES : NO;
 1027: }
 1028: 
 1029: - (void)goBack
 1030: {
 1031:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 1032: 
 1033:   nsresult rv = nav->GoBack();
 1034:   if (NS_FAILED(rv)) {
 1035:     // XXX need to throw
 1036:   }  
 1037: }
 1038: 
 1039: - (void)goForward
 1040: {
 1041:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 1042: 
 1043:   nsresult rv = nav->GoForward();
 1044:   if (NS_FAILED(rv)) {
 1045:     // XXX need to throw
 1046:   }  
 1047: }
 1048: 
 1049: - (void)gotoIndex:(int)index
 1050: {
 1051:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 1052: 
 1053:   nsresult rv = nav->GotoIndex(index);
 1054:   if (NS_FAILED(rv)) {
 1055:     // XXX need to throw
 1056:   }    
 1057: }
 1058: 
 1059: - (void)stop:(unsigned int)flags
 1060: {
 1061:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 1062: 
 1063:   nsresult rv = nav->Stop(flags);
 1064:   if (NS_FAILED(rv)) {
 1065:     // XXX need to throw
 1066:   }    
 1067: }
 1068: 
 1069: - (NSURL*)getCurrentURI
 1070: {
 1071:   nsCOMPtr<nsIURI> uri;
 1072:   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
 1073: 
 1074:   nav->GetCurrentURI(getter_AddRefs(uri));
 1075:   if (!uri) {
 1076:     return nsnull;
 1077:   }
 1078: 
 1079:   nsXPIDLCString spec;
 1080:   uri->GetSpec(getter_Copies(spec));
 1081:   
 1082:   const char* cstr = spec.get();
 1083:   NSString* str = [NSString stringWithCString:cstr];
 1084:   NSURL* url = [NSURL URLWithString:str];
 1085:   
 1086:   return url;
 1087: }
 1088: 
 1089: - (nsIWebBrowser*)getWebBrowser
 1090: {
 1091:   NS_IF_ADDREF(_webBrowser);
 1092:   return _webBrowser;
 1093: }
 1094: 
 1095: - (void)setWebBrowser:(nsIWebBrowser*)browser
 1096: {
 1097:   _webBrowser = browser;
 1098: 
 1099:   if (_webBrowser) {
 1100:     // Set the container nsIWebBrowserChrome
 1101:     _webBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome *, 
 1102: 						   _listener));
 1103: 
 1104:     NSRect frame = [self frame];
 1105:  
 1106:     // Hook up the widget hierarchy with us as the parent
 1107:     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
 1108:     baseWin->InitWindow((NSView*)self, nsnull, 0, 0, 
 1109: 			frame.size.width, frame.size.height);
 1110:     baseWin->Create();
 1111:   }
 1112: 
 1113: }
 1114: 
 1115: -(void) saveInternal: (nsIURI*)aURI
 1116:         withDocument: (nsIDOMDocument*)aDocument
 1117:         bypassCache: (BOOL)aBypassCache
 1118:         filterView: (NSView*)aFilterView
 1119:         filterList: (NSPopUpButton*)aFilterList
 1120: {
 1121:     // Create our web browser persist object.  This is the object that knows
 1122:     // how to actually perform the saving of the page (and of the images
 1123:     // on the page).
 1124:     nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
 1125:     if (!webPersist)
 1126:         return;
 1127:     
 1128:     // Make a temporary file object that we can save to.
 1129:     nsCOMPtr<nsIProperties> dirService(do_GetService(dirServiceContractID));
 1130:     if (!dirService)
 1131:         return;
 1132:     nsCOMPtr<nsIFile> tmpFile;
 1133:     dirService->Get("TmpD", NS_GET_IID(nsIFile), getter_AddRefs(tmpFile));
 1134:     static short unsigned int tmpRandom = 0;
 1135:     nsCAutoString tmpNo; tmpNo.AssignWithConversion(tmpRandom++);
 1136:     nsCAutoString saveFile("-sav");
 1137:     saveFile += tmpNo;
 1138:     saveFile += "tmp";
 1139:     tmpFile->Append(saveFile.get()); 
 1140:     
 1141:     // Get the post data if we're an HTML doc.
 1142:     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(_webBrowser));
 1143:     nsCOMPtr<nsISHistory> sessionHistory;
 1144:     webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
 1145:     nsCOMPtr<nsIHistoryEntry> entry;
 1146:     PRInt32 sindex;
 1147:     sessionHistory->GetIndex(&sindex);
 1148:     sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
 1149:     nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
 1150:     nsCOMPtr<nsIInputStream> postData;
 1151:     if (shEntry)
 1152:         shEntry->GetPostData(getter_AddRefs(postData));
 1153:     
 1154:     nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI, 
 1155:                                                    aDocument, postData, aBypassCache,
 1156:                                                    aFilterView, aFilterList);
 1157:     if (!sniffer)
 1158:         return;
 1159:     webPersist->SetProgressListener(sniffer);
 1160:     webPersist->SaveURI(aURI, nsnull, tmpFile);
 1161: }
 1162: 
 1163: -(void)printDocument
 1164: {
 1165:     nsCOMPtr<nsIDOMWindow> domWindow;
 1166:     _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 1167:     nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(domWindow));
 1168:     nsCOMPtr<nsIWebBrowserPrint> print;
 1169:     ir->GetInterface(NS_GET_IID(nsIWebBrowserPrint), getter_AddRefs(print));
 1170:     print->Print(nsnull, nsnull);
 1171: }
 1172: 
 1173: -(void)printPreview
 1174: {
 1175:     nsCOMPtr<nsIDOMWindow> domWindow;
 1176:     _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 1177:     nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(domWindow));
 1178:     nsCOMPtr<nsIWebBrowserPrint> print;
 1179:     ir->GetInterface(NS_GET_IID(nsIWebBrowserPrint), getter_AddRefs(print));
 1180:     print->PrintPreview(nsnull);
 1181: }
 1182: 
 1183: -(void)findInPage
 1184: {
 1185:     FindDlgController* findDialog = [[FindDlgController alloc] initWithWindowNibName: @"FindDialog"];
 1186:     nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
 1187:     nsCOMPtr<nsIDOMWindow> rootWindow;
 1188:     nsCOMPtr<nsIDOMWindow> focusedWindow;
 1189:     _webBrowser->GetContentDOMWindow(getter_AddRefs(rootWindow));
 1190:     wbf->GetFocusedWindow(getter_AddRefs(focusedWindow));
 1191:     if (!focusedWindow)
 1192:         focusedWindow = rootWindow;
 1193:     nsCOMPtr<nsIWebBrowserFind> webFind(do_GetInterface(_webBrowser));
 1194:     nsCOMPtr<nsIWebBrowserFindInFrames> framesFind(do_QueryInterface(webFind));
 1195:     framesFind->SetRootSearchFrame(rootWindow);
 1196:     framesFind->SetCurrentSearchFrame(focusedWindow);
 1197:     
 1198:     [findDialog setFind: webFind];
 1199:     [findDialog showWindow: findDialog];
 1200: }
 1201: 
 1202: -(void)findAgain
 1203: {
 1204: }
 1205: 
 1206: -(void)saveDocument: (NSView*)aFilterView filterList: (NSPopUpButton*)aFilterList
 1207: {
 1208:     nsCOMPtr<nsIWebBrowserFocus> wbf(do_QueryInterface(_webBrowser));
 1209:     nsCOMPtr<nsIDOMWindow> domWindow;
 1210:     wbf->GetFocusedWindow(getter_AddRefs(domWindow));
 1211:     if (!domWindow)
 1212:         _webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 1213:     if (!domWindow)
 1214:         return;
 1215:     
 1216:     nsCOMPtr<nsIDOMDocument> domDocument;
 1217:     domWindow->GetDocument(getter_AddRefs(domDocument));
 1218:     if (!domDocument)
 1219:         return;
 1220:     nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDocument));
 1221:     if (!doc)
 1222:         return;
 1223:     nsCOMPtr<nsIURI> url;
 1224:     doc->GetDocumentURL(getter_AddRefs(url));
 1225:      
 1226:     [self saveInternal: url.get()
 1227:           withDocument: domDocument
 1228:           bypassCache: NO
 1229:           filterView: aFilterView
 1230:           filterList: aFilterList];
 1231: }
 1232: 
 1233: 
 1234: -(IBAction)cut:(id)aSender
 1235: {
 1236:     nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 1237:     clipboard->CutSelection();
 1238: }
 1239: 
 1240: -(IBAction)copy:(id)aSender
 1241: {
 1242:     nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 1243:     clipboard->CopySelection();
 1244: }
 1245: 
 1246: -(IBAction)paste:(id)aSender
 1247: {
 1248:     nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 1249:     clipboard->Paste();
 1250: }
 1251: 
 1252: -(IBAction)clear:(id)aSender
 1253: {
 1254:     nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 1255:     clipboard->SelectNone();
 1256: }
 1257: 
 1258: -(IBAction)selectAll:(id)aSender
 1259: {
 1260:     nsCOMPtr<nsIClipboardCommands> clipboard(do_GetInterface(_webBrowser));
 1261:     clipboard->SelectAll();
 1262: }
 1263: 
 1264: @end
 1265: 

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