240 lines
8.6 KiB
C++
240 lines
8.6 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla 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/MPL/
|
|
*
|
|
* 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):
|
|
* Conrad Carlen <ccarlen@netscape.com>
|
|
*
|
|
* 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 MPL, 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 MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "CWindowCreator.h"
|
|
|
|
#include "nsIWindowWatcher.h"
|
|
#include "nsIServiceManagerUtils.h"
|
|
|
|
#include "CBrowserShell.h"
|
|
#include "CBrowserWindow.h"
|
|
#include "ApplIDs.h"
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CWindowCreator
|
|
// ---------------------------------------------------------------------------
|
|
|
|
NS_IMPL_ISUPPORTS1(CWindowCreator, nsIWindowCreator);
|
|
|
|
CWindowCreator::CWindowCreator()
|
|
{
|
|
NS_INIT_ISUPPORTS();
|
|
}
|
|
|
|
CWindowCreator::~CWindowCreator()
|
|
{
|
|
}
|
|
|
|
NS_IMETHODIMP CWindowCreator::CreateChromeWindow(nsIWebBrowserChrome *aParent,
|
|
PRUint32 aChromeFlags,
|
|
nsIWebBrowserChrome **_retval)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(_retval);
|
|
*_retval = 0;
|
|
|
|
// we're ignoring aParent,
|
|
// but since windows on the Mac don't have parents anyway...
|
|
try {
|
|
LWindow *theWindow = CreateWindowInternal(aChromeFlags, -1, -1);
|
|
CBrowserShell *browser = dynamic_cast<CBrowserShell*>(theWindow->FindPaneByID(CBrowserShell::paneID_MainBrowser));
|
|
ThrowIfNil_(browser);
|
|
browser->GetWebBrowserChrome(_retval);
|
|
} catch(...) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
InitializeWindowCreator creates and hands off an object with a callback
|
|
to a window creation function. This will be used by Gecko C++ code
|
|
(never JS) to create new windows when no previous window is handy
|
|
to begin with. This is done in a few exceptional cases, like PSM code.
|
|
Failure to set this callback will only disable the ability to create
|
|
new windows under these circumstances.
|
|
*/
|
|
|
|
nsresult CWindowCreator::Initialize()
|
|
{
|
|
// Create a CWindowCreator and give it to the WindowWatcher service
|
|
// The WindowWatcher service will own it so we don't keep a ref.
|
|
CWindowCreator *windowCreator = new CWindowCreator;
|
|
if (!windowCreator) return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
|
|
if (!wwatch) return NS_ERROR_FAILURE;
|
|
return wwatch->SetWindowCreator(windowCreator);
|
|
}
|
|
|
|
LWindow* CWindowCreator::CreateWindowInternal(PRUint32 inChromeFlags,
|
|
PRInt32 width, PRInt32 height)
|
|
{
|
|
const SInt16 kStatusBarHeight = 16;
|
|
|
|
LWindow *theWindow;
|
|
PRUint32 chromeFlags;
|
|
|
|
if (inChromeFlags == nsIWebBrowserChrome::CHROME_DEFAULT)
|
|
chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_RESIZE |
|
|
nsIWebBrowserChrome::CHROME_WINDOW_CLOSE |
|
|
nsIWebBrowserChrome::CHROME_TOOLBAR |
|
|
nsIWebBrowserChrome::CHROME_STATUSBAR;
|
|
else
|
|
chromeFlags = inChromeFlags;
|
|
|
|
// Bounds - Set to an arbitrary rect - we'll size it after all the subviews are in.
|
|
Rect globalBounds;
|
|
globalBounds.left = 4;
|
|
globalBounds.top = 42;
|
|
globalBounds.right = globalBounds.left + 600;
|
|
globalBounds.bottom = globalBounds.top + 400;
|
|
|
|
// ProcID and attributes
|
|
short windowDefProc;
|
|
UInt32 windowAttrs = (windAttr_Enabled | windAttr_Targetable);
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG)
|
|
{
|
|
windowAttrs |= windAttr_Modal;
|
|
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_TITLEBAR)
|
|
{
|
|
windowDefProc = kWindowMovableModalDialogProc;
|
|
windowAttrs |= windAttr_TitleBar;
|
|
}
|
|
else
|
|
windowDefProc = kWindowModalDialogProc;
|
|
}
|
|
else
|
|
{
|
|
windowAttrs |= windAttr_Regular;
|
|
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE)
|
|
{
|
|
windowDefProc = kWindowGrowDocumentProc;
|
|
windowAttrs |= windAttr_Resizable;
|
|
}
|
|
else
|
|
windowDefProc = kWindowDocumentProc;
|
|
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_CLOSE)
|
|
windowAttrs |= windAttr_CloseBox;
|
|
}
|
|
|
|
theWindow = new CBrowserWindow(LCommander::GetTopCommander(), globalBounds, "\p", windowDefProc, windowAttrs, window_InFront);
|
|
ThrowIfNil_(theWindow);
|
|
|
|
SDimension16 windowSize, toolBarSize;
|
|
theWindow->GetFrameSize(windowSize);
|
|
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_TOOLBAR)
|
|
{
|
|
LView::SetDefaultView(theWindow);
|
|
LCommander::SetDefaultCommander(theWindow);
|
|
LAttachable::SetDefaultAttachable(nil);
|
|
|
|
LView *toolBarView = static_cast<LView*>(UReanimator::ReadObjects(ResType_PPob, 131));
|
|
ThrowIfNil_(toolBarView);
|
|
|
|
toolBarView->GetFrameSize(toolBarSize);
|
|
toolBarView->PlaceInSuperFrameAt(0, 0, false);
|
|
toolBarSize.width = windowSize.width;
|
|
toolBarView->ResizeFrameTo(toolBarSize.width, toolBarSize.height, false);
|
|
}
|
|
|
|
SPaneInfo aPaneInfo;
|
|
SViewInfo aViewInfo;
|
|
|
|
aPaneInfo.paneID = CBrowserShell::paneID_MainBrowser;
|
|
aPaneInfo.width = windowSize.width;
|
|
aPaneInfo.height = windowSize.height;
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_TOOLBAR)
|
|
aPaneInfo.height -= toolBarSize.height;
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_STATUSBAR)
|
|
aPaneInfo.height -= kStatusBarHeight - 1;
|
|
aPaneInfo.visible = true;
|
|
aPaneInfo.enabled = true;
|
|
aPaneInfo.bindings.left = true;
|
|
aPaneInfo.bindings.top = true;
|
|
aPaneInfo.bindings.right = true;
|
|
aPaneInfo.bindings.bottom = true;
|
|
aPaneInfo.left = 0;
|
|
aPaneInfo.top = (chromeFlags & nsIWebBrowserChrome::CHROME_TOOLBAR) ? toolBarSize.height : 0;
|
|
aPaneInfo.userCon = 0;
|
|
aPaneInfo.superView = theWindow;
|
|
|
|
aViewInfo.imageSize.width = 0;
|
|
aViewInfo.imageSize.height = 0;
|
|
aViewInfo.scrollPos.h = aViewInfo.scrollPos.v = 0;
|
|
aViewInfo.scrollUnit.h = aViewInfo.scrollUnit.v = 1;
|
|
aViewInfo.reconcileOverhang = 0;
|
|
|
|
CBrowserShell *aShell = new CBrowserShell(aPaneInfo, aViewInfo, chromeFlags, PR_TRUE);
|
|
ThrowIfNil_(aShell);
|
|
aShell->AddAttachments();
|
|
aShell->PutInside(theWindow, false);
|
|
|
|
if (chromeFlags & nsIWebBrowserChrome::CHROME_STATUSBAR)
|
|
{
|
|
LView::SetDefaultView(theWindow);
|
|
LCommander::SetDefaultCommander(theWindow);
|
|
LAttachable::SetDefaultAttachable(nil);
|
|
|
|
LView *statusView = static_cast<LView*>(UReanimator::ReadObjects(ResType_PPob, 130));
|
|
ThrowIfNil_(statusView);
|
|
|
|
statusView->PlaceInSuperFrameAt(0, windowSize.height - kStatusBarHeight + 1, false);
|
|
statusView->ResizeFrameTo(windowSize.width - 15, kStatusBarHeight, false);
|
|
}
|
|
|
|
// Now the window is constructed...
|
|
theWindow->FinishCreate();
|
|
|
|
Rect theBounds;
|
|
theWindow->GetGlobalBounds(theBounds);
|
|
if (width == -1)
|
|
width = theBounds.right - theBounds.left;
|
|
if (height == -1)
|
|
height = theBounds.bottom - theBounds.top;
|
|
|
|
theWindow->ResizeWindowTo(width, height);
|
|
|
|
return theWindow;
|
|
}
|