File:  [mozdev] / chimera / MyBrowserView.mm
Revision 1.25: download - view: text, annotated - select for diffs - revision graph
Sun Mar 10 19:26:16 2002 UTC (17 years, 9 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Full implementation of window autosaving (including correct ignoring of windows opened as popups by web pages.

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Netscape Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/NPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is 
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2002
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the NPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the NPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#import "MyBrowserView.h"
#import "BrowserWindowController.h"

#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIIOService.h"
#include "ContentClickListener.h"
#include "nsIDOMWindow.h"
#include "nsIChromeEventHandler.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMEventReceiver.h"

#define DOCUMENT_DONE_STRING @"Document: Done"
#define LOADING_STRING @"Loading..."

static const char* ioServiceContractID = "@mozilla.org/network/io-service;1";

@implementation MyBrowserView

-(void)windowClosed
{
    // Break the cycle.
    [browserView setContainer: nil];
    [browserView removeListener: self];
    [browserView destroyWebBrowser];
}

-(void)dealloc
{
    printf("My browser view died.\n");
    
    [[NSNotificationCenter defaultCenter] removeObserver: self];
    
	[defaultStatus release];
    [loadingStatus release];
    
	[super dealloc];
}

- (IBAction)load:(id)sender
{
  [browserView loadURI:[NSURL URLWithString:[urlbar stringValue]] flags:NSLoadFlagsNone];
}

-(void)disconnectView
{
    urlbar = nil;
    status = nil;
    progress = nil;
    progressSuper = nil;
    mIsPrimary = NO;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    [browserView setActive: NO];
}

- (id)initWithFrame:(NSRect)frameRect
{
    [super initWithFrame: frameRect];
     browserView = [[[NSBrowserView alloc] initWithFrame:[self bounds]] autorelease];
    [self addSubview:browserView];
    [browserView setContainer:self];
    [browserView addListener:self];
    mIsBusy = NO;
    mListenersAttached = NO;
    return self;
}

-(void)setTab: (NSTabViewItem*)tab
{
  mTab = tab;
}

-(void)makePrimaryBrowserView: (id)aUrlbar status: (id)aStatus
    progress: (id)aProgress windowController: aWindowController
{
  urlbar = aUrlbar;
  status = aStatus;
  progress = aProgress;
  progressSuper = [aProgress superview];
  mWindowController = aWindowController;
  
  if (!mIsBusy)
      [progress removeFromSuperview];
  
  defaultStatus = NULL;
  loadingStatus = DOCUMENT_DONE_STRING;
  [status setStringValue:loadingStatus];
  
  mIsPrimary = YES;
 
  nsCOMPtr<nsIIOService> ioService(do_GetService(ioServiceContractID));
  if (!ioService)
    return;
  PRBool offline = PR_FALSE;
  ioService->GetOffline(&offline);
  mOffline = offline;
  
  if (mWindowController) // Only register if we're the content area.
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(offlineModeChanged:)
        name:@"offlineModeChanged"
        object:nil];
        
  // Update the URL bar.
  [mWindowController updateLocationFields:[self getCurrentURLSpec]];
  
  if (mWindowController && !mListenersAttached) {
    mListenersAttached = YES;
    
    // We need to hook up our click and context menu listeners.
    ContentClickListener* clickListener = new ContentClickListener(mWindowController);
    if (!clickListener)
      return;
    
    nsCOMPtr<nsIDOMWindow> contentWindow = getter_AddRefs([[self getBrowserView] getContentWindow]);
    nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(contentWindow));
    nsCOMPtr<nsIChromeEventHandler> chromeHandler;
    piWindow->GetChromeEventHandler(getter_AddRefs(chromeHandler));
    nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(chromeHandler));
    rec->AddEventListenerByIID(clickListener, NS_GET_IID(nsIDOMMouseListener));
  }
}

-(NSString*)getCurrentURLSpec
{
  return [browserView getCurrentURLSpec];
}

- (void)awakeFromNib 
{
}

- (void)setFrame:(NSRect)frameRect
{
  [super setFrame:frameRect];
  NSRect bounds = [self bounds];
  [browserView setFrame:bounds];
}

-(BOOL)isBusy
{
  return mIsBusy;
}

- (void)onLoadingStarted 
{
  if (defaultStatus) {
    [defaultStatus release];
    defaultStatus = NULL;
  }

  [progressSuper addSubview:progress];
  [progress setIndeterminate:YES];
  [progress startAnimation:self];

  loadingStatus = LOADING_STRING;
  [status setStringValue:loadingStatus];

  mIsBusy = YES;
  [mTab setLabel: LOADING_STRING];
  
  if (mWindowController)
    [mWindowController updateToolbarItems];
}

- (void)onLoadingCompleted:(BOOL)succeeded
{
  [progress setIndeterminate:YES];
  [progress stopAnimation:self];
  [progress removeFromSuperview];

  loadingStatus = DOCUMENT_DONE_STRING;
  if (defaultStatus) {
    [status setStringValue:defaultStatus];
  }
  else {
    [status setStringValue:loadingStatus];
  }

  mIsBusy = NO;
  
  if (mWindowController)
    [mWindowController updateToolbarItems];
}

- (void)onProgressChange:(int)currentBytes outOf:(int)maxBytes 
{
  if (maxBytes > 0) {
    BOOL isIndeterminate = [progress isIndeterminate];
    if (isIndeterminate) {
      [progress setIndeterminate:NO];
    }
    double val = ((double)currentBytes / (double)maxBytes) * 100.0;
    [progress setDoubleValue:val];
  }
}

- (void)onLocationChange:(NSURL*)url 
{
  NSString* spec = [url absoluteString];
  [mWindowController updateLocationFields:spec];
}

- (void)onStatusChange:(NSString*)aStatusString
{
  [status setStringValue: aStatusString];
}

- (void)setStatus:(NSString *)statusString ofType:(NSStatusType)type 
{
  if (type == NSStatusTypeScriptDefault) {
    if (defaultStatus) {
      [defaultStatus release];
    }
    defaultStatus = statusString;
    if (defaultStatus) {
      [defaultStatus retain];
    }
  }
  else if (!statusString) {
    if (defaultStatus) {
      [status setStringValue:defaultStatus];
    }
    else {
      [status setStringValue:loadingStatus];
    }      
  }
  else {
    [status setStringValue:statusString];
  }
}

- (NSString *)title 
{
  return [[mWindowController window] title];
}

- (void)setTitle:(NSString *)title
{
    // We must be the primary content area.
    if (mIsPrimary && mWindowController) {
        if (mOffline) {
            NSString* newTitle;
            if (title && ![title isEqualToString:@""])
                newTitle = [title stringByAppendingString: @" [Working Offline]"];
            else
                newTitle = @"Untitled [Working Offline]";
            [[mWindowController window] setTitle: newTitle];
        }
        else {
            if (title && ![title isEqualToString:@""])
                [[mWindowController window] setTitle:title];
            else
                [[mWindowController window] setTitle:@"Untitled"];
        }
    }
    
    // Always set the tab.
    if (title && ![title isEqualToString:@""])
        [mTab setLabel:title];
    else
        [mTab setLabel:@"Untitled"];
}

- (void)offlineModeChanged: (NSNotification*)aNotification
{
    nsCOMPtr<nsIIOService> ioService(do_GetService(ioServiceContractID));
    if (!ioService)
        return;
    PRBool offline = PR_FALSE;
    ioService->GetOffline(&offline);
    mOffline = offline;
    
    if (mOffline) {
        NSString* newTitle = [[[mWindowController window] title] stringByAppendingString: @" [Working Offline]"];
        [[mWindowController window] setTitle: newTitle];
    }
    else {
        NSArray* titleItems = [[[mWindowController window] title] componentsSeparatedByString:@" [Working Offline]"];
        [[mWindowController window] setTitle: [titleItems objectAtIndex: 0]];
    }
}

- (void)sizeBrowserTo:(NSSize)dimensions
{
  NSRect bounds = [self bounds];
  float dx = dimensions.width - bounds.size.width;
  float dy = dimensions.height - bounds.size.height;

  NSRect frame = [[self window] frame];
  frame.size.width += dx;
  frame.size.height += dy;

  [[self window] setFrame:frame display:YES];
}

- (NSBrowserView*)createBrowserWindow:(unsigned int)mask
{
  BrowserWindowController* controller = [[BrowserWindowController alloc] initWithWindowNibName: @"BrowserWindow"];
  [controller disableAutosave]; // The Web page opened this window, so we don't ever use its settings.
  [controller enterModalSession];
  return [[controller getMyBrowserView] getBrowserView];
}

- (NSBrowserView*)getBrowserView
{
  return browserView;
}

@end

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