Bug 66036 - Make viewer use nsIFilePicker instead of nsIFileWidget.

This required several fixes to make viewer able to display Linux's XUL
filepicker correctly, including making modal dialogs work, delaying the
showing of chrome windows until the document has fully loaded, and fixing
the problem on gtk where space was reserved for a menubar even if the
window doesn't have one.

r=jag, sr=shaver.
This commit is contained in:
bryner%netscape.com 2001-08-14 05:21:54 +00:00
parent 1c359a6c9e
commit 39f0e0f79e
7 changed files with 162 additions and 62 deletions

View File

@ -19,6 +19,7 @@
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Brian Ryner <bryner@netscape.com>
* This Original Code has been modified by IBM Corporation. Modifications made by IBM
* described herein are Copyright (c) International Business Machines Corporation, 2000.
* Modifications to Mozilla code or documentation identified per MPL Section 3.3
@ -45,7 +46,9 @@
#include "nsIDOMDocument.h"
#include "nsIURL.h"
#include "nsIChannel.h"
#include "nsIFileWidget.h"
#include "nsIDOMWindowInternal.h"
#include "nsIFilePicker.h"
#include "nsIFileChannel.h"
#include "nsILookAndFeel.h"
#include "nsIComponentManager.h"
#include "nsIFactory.h"
@ -171,7 +174,6 @@ static NS_DEFINE_CID(kWalletServiceCID, NS_WALLETSERVICE_CID);
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
static NS_DEFINE_CID(kButtonCID, NS_BUTTON_CID);
static NS_DEFINE_CID(kFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_CID(kTextFieldCID, NS_TEXTFIELD_CID);
static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID);
static NS_DEFINE_CID(kWindowCID, NS_WINDOW_CID);
@ -185,7 +187,6 @@ static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIWebShellContainerIID, NS_IWEB_SHELL_CONTAINER_IID);
@ -1090,58 +1091,67 @@ nsBrowserWindow::GoTo(const PRUnichar* aURL)
}
static PRBool GetFileFromFileSelector(nsIWidget* aParentWindow,
nsFileSpec& aFileSpec,
nsFileSpec& aDisplayDirectory)
static PRBool GetFileFromFileSelector(nsIDOMWindowInternal* aParentWindow,
nsILocalFile **aFile,
nsILocalFile **aDisplayDirectory)
{
PRBool selectedFileName = PR_FALSE;
nsIFileWidget *fileWidget;
nsString title; title.AssignWithConversion("Open HTML");
nsresult rv = nsComponentManager::CreateInstance(kFileWidgetCID,
nsnull,
kIFileWidgetIID,
(void**)&fileWidget);
if (NS_OK == rv) {
// STRING USE WARNING: this section really needs to be looked at
nsString titles[] = {NS_ConvertASCIItoUCS2("All Readable Files"), NS_ConvertASCIItoUCS2("HTML Files"),
NS_ConvertASCIItoUCS2("XML Files"), NS_ConvertASCIItoUCS2("Image Files"), NS_ConvertASCIItoUCS2("All Files")};
nsString filters[] = {NS_ConvertASCIItoUCS2("*.htm; *.html; *.xml; *.gif; *.jpg; *.jpeg; *.png"),
NS_ConvertASCIItoUCS2("*.htm; *.html"),
NS_ConvertASCIItoUCS2("*.xml"),
NS_ConvertASCIItoUCS2("*.gif; *.jpg; *.jpeg; *.png"),
NS_ConvertASCIItoUCS2("*.*")};
fileWidget->SetFilterList(5, titles, filters);
nsresult rv;
nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1");
fileWidget->SetDisplayDirectory(aDisplayDirectory);
fileWidget->Create(aParentWindow,
title,
eMode_load,
nsnull,
nsnull);
if (filePicker) {
rv = filePicker->Init(aParentWindow, NS_LITERAL_STRING("Open HTML").get(),
nsIFilePicker::modeOpen);
if (NS_SUCCEEDED(rv)) {
filePicker->AppendFilters(nsIFilePicker::filterAll | nsIFilePicker::filterHTML |
nsIFilePicker::filterXML | nsIFilePicker::filterImages);
if (*aDisplayDirectory)
filePicker->SetDisplayDirectory(*aDisplayDirectory);
PRInt16 dialogResult;
rv = filePicker->Show(&dialogResult);
if (NS_FAILED(rv) || dialogResult == nsIFilePicker::returnCancel)
return PR_FALSE;
PRUint32 result = fileWidget->Show();
if (result) {
fileWidget->GetFile(aFileSpec);
selectedFileName = PR_TRUE;
filePicker->GetFile(aFile);
if (*aFile) {
NS_IF_RELEASE(*aDisplayDirectory);
filePicker->GetDisplayDirectory(aDisplayDirectory);
return PR_TRUE;
}
}
fileWidget->GetDisplayDirectory(aDisplayDirectory);
NS_RELEASE(fileWidget);
}
return selectedFileName;
return PR_FALSE;
}
void
nsBrowserWindow::DoFileOpen()
{
nsFileSpec fileSpec;
if (GetFileFromFileSelector(mWindow, fileSpec, mOpenFileDirectory)) {
nsFileURL fileURL(fileSpec);
// Ask the Web widget to load the file URL
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
webNav->LoadURI(NS_ConvertASCIItoUCS2(fileURL.GetURLString()).get(), nsIWebNavigation::LOAD_FLAGS_NONE);
SetVisibility(PR_TRUE);
nsCOMPtr<nsILocalFile> file;
nsCOMPtr<nsIDOMWindow> domWindow;
nsCOMPtr<nsIDOMWindowInternal> parentWindow;
nsresult rv;
// get nsIDOMWindowInternal interface for nsIFilePicker
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (NS_SUCCEEDED(rv))
parentWindow = do_QueryInterface(domWindow);
if (GetFileFromFileSelector(parentWindow, getter_AddRefs(file),
getter_AddRefs(mOpenFileDirectory))) {
nsCOMPtr<nsIFileURL> fileURL = do_CreateInstance(NS_STANDARDURL_CONTRACTID);
if (fileURL) {
fileURL->SetFile(file);
nsXPIDLCString url;
fileURL->GetSpec(getter_Copies(url));
// Ask the Web widget to load the file URL
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
webNav->LoadURI(NS_ConvertASCIItoUCS2(url.get()).get(),
nsIWebNavigation::LOAD_FLAGS_NONE);
SetVisibility(PR_TRUE);
}
}
}
@ -1434,6 +1444,7 @@ nsBrowserWindow::Init(nsIAppShell* aAppShell,
if (NS_OK != rv) {
return rv;
}
mHaveMenuBar = PR_TRUE;
mWindow->GetClientBounds(r);
r.x = r.y = 0;
}

View File

@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@netscape.com>
*/
#ifndef nsBrowserWindow_h___
#define nsBrowserWindow_h___
@ -223,7 +224,7 @@ public:
nsCOMPtr<nsIDocShell> mDocShell;
nsCOMPtr<nsIWebBrowser> mWebBrowser;
nsFileSpec mOpenFileDirectory;
nsCOMPtr<nsILocalFile> mOpenFileDirectory;
PRTime mLoadStartTime;
PRBool mShowLoadTimes;
@ -263,6 +264,7 @@ protected:
virtual ~nsBrowserWindow();
nsWebBrowserChrome* mWebBrowserChrome;
PRBool mHaveMenuBar;
};
// XXX This is bad; because we can't hang a closure off of the event

View File

@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@netscape.com>
*/
#ifdef NGPREFS
@ -669,7 +670,7 @@ nsViewerApp::OpenWindow()
bw->SetApp(this);
bw->SetShowLoadTimes(mShowLoadTimes);
bw->Init(mAppShell, nsRect(0, 0, mWidth, mHeight),
PRUint32(~0), mAllowPlugins);
(PRUint32(~0) & ~nsIWebBrowserChrome::CHROME_OPENAS_CHROME), mAllowPlugins);
bw->SetVisibility(PR_TRUE);
nsBrowserWindow* bwCurrent;
mCrawler->GetBrowserWindow(&bwCurrent);
@ -757,7 +758,9 @@ nsViewerApp::OpenWindow(PRUint32 aNewChromeMask, nsBrowserWindow*& aNewWindow)
bw->SetApp(this);
bw->Init(mAppShell, nsRect(0, 0, 620, 400), aNewChromeMask, mAllowPlugins);
bw->SetVisibility(PR_TRUE);
// Defer showing chrome windows until the chrome has loaded
if (!(aNewChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
bw->SetVisibility(PR_TRUE);
aNewWindow = bw;

View File

@ -18,6 +18,7 @@
*
* Contributor(s):
* Travis Bogard <travis@netscape.com>
* Brian Ryner <bryner@netscape.com>
*/
// Local Includes
@ -38,7 +39,12 @@
#include "nsIURI.h"
#include "nsIDOMWindow.h"
struct JSContext;
#include "nsIJSContextStack.h"
// CIDs
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
//*****************************************************************************
//*** nsWebBrowserChrome: Object Management
@ -49,7 +55,12 @@ nsWebBrowserChrome::nsWebBrowserChrome() : mBrowserWindow(nsnull), mTimerSet(PR_
{
NS_INIT_REFCNT();
mActiveDocuments = 0;
mActiveDocuments = 0;
mChromeFlags = 0;
mSizeSet = PR_FALSE;
mContinueModalLoop = PR_FALSE;
mModalStatus = NS_OK;
mChromeLoaded = PR_FALSE;
}
nsWebBrowserChrome::~nsWebBrowserChrome()
@ -117,14 +128,14 @@ NS_IMETHODIMP nsWebBrowserChrome::GetWebBrowser(nsIWebBrowser** aWebBrowser)
NS_IMETHODIMP nsWebBrowserChrome::SetChromeFlags(PRUint32 aChromeFlags)
{
NS_ERROR("Haven't Implemented this yet");
return NS_ERROR_FAILURE;
mChromeFlags = aChromeFlags;
return NS_OK;
}
NS_IMETHODIMP nsWebBrowserChrome::GetChromeFlags(PRUint32* aChromeFlags)
{
NS_ERROR("Haven't Implemented this yet");
return NS_ERROR_FAILURE;
*aChromeFlags = mChromeFlags;
return NS_OK;
}
NS_IMETHODIMP nsWebBrowserChrome::CreateBrowserWindow(PRUint32 aChromeMask,
@ -142,6 +153,7 @@ NS_IMETHODIMP nsWebBrowserChrome::CreateBrowserWindow(PRUint32 aChromeMask,
mBrowserWindow->mApp->OpenWindow(aChromeMask, browser);
NS_ENSURE_TRUE(browser, NS_ERROR_FAILURE);
browser->mWebBrowserChrome->SetChromeFlags(aChromeMask);
*aWebBrowser = browser->mWebBrowser;
NS_IF_ADDREF(*aWebBrowser);
@ -150,6 +162,7 @@ NS_IMETHODIMP nsWebBrowserChrome::CreateBrowserWindow(PRUint32 aChromeMask,
NS_IMETHODIMP nsWebBrowserChrome::DestroyBrowserWindow()
{
ExitModalEventLoop(NS_OK);
return mBrowserWindow->Destroy();
}
@ -187,6 +200,7 @@ NS_IMETHODIMP nsWebBrowserChrome::FindNamedBrowserItem(const PRUnichar* aName,
NS_IMETHODIMP nsWebBrowserChrome::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
{
mSizeSet = PR_TRUE;
mBrowserWindow->mWindow->Resize(aCX, aCY, PR_FALSE);
mBrowserWindow->Layout(aCX, aCY);
@ -195,20 +209,62 @@ NS_IMETHODIMP nsWebBrowserChrome::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
NS_IMETHODIMP nsWebBrowserChrome::ShowAsModal()
{
NS_ERROR("Haven't Implemented this yet");
return NS_ERROR_FAILURE;
/* Copied from nsXULWindow */
nsCOMPtr<nsIAppShell> appShell(do_CreateInstance(kAppShellCID));
if (!appShell)
return NS_ERROR_FAILURE;
appShell->Create(0, nsnull);
appShell->Spinup();
// Store locally so it doesn't die on us
nsCOMPtr<nsIWidget> window = mBrowserWindow->mWindow;
window->SetModal(PR_TRUE);
mContinueModalLoop = PR_TRUE;
EnableParent(PR_FALSE);
nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1"));
nsresult rv = NS_OK;
if (stack && NS_SUCCEEDED(stack->Push(nsnull))) {
while (NS_SUCCEEDED(rv) && mContinueModalLoop) {
void* data;
PRBool isRealEvent;
PRBool processEvent;
rv = appShell->GetNativeEvent(isRealEvent, data);
if (NS_SUCCEEDED(rv)) {
window->ModalEventFilter(isRealEvent, data, &processEvent);
if (processEvent)
appShell->DispatchNativeEvent(isRealEvent, data);
}
}
JSContext* cx;
stack->Pop(&cx);
NS_ASSERTION(!cx, "JSContextStack mismatch");
} else
rv = NS_ERROR_FAILURE;
mContinueModalLoop = PR_FALSE;
window->SetModal(PR_FALSE);
appShell->Spindown();
return mModalStatus;
}
NS_IMETHODIMP nsWebBrowserChrome::IsWindowModal(PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
*_retval = mContinueModalLoop;
return NS_OK;
}
NS_IMETHODIMP nsWebBrowserChrome::ExitModalEventLoop(nsresult aStatus)
{
NS_ERROR("Haven't Implemented this yet");
return NS_ERROR_FAILURE;
if (mContinueModalLoop)
EnableParent(PR_TRUE);
mContinueModalLoop = PR_FALSE;
mModalStatus = aStatus;
return NS_OK;
}
//*****************************************************************************
@ -281,7 +337,11 @@ NS_IMETHODIMP nsWebBrowserChrome::GetVisibility(PRBool *aVisibility)
NS_IMETHODIMP nsWebBrowserChrome::SetVisibility(PRBool aVisibility)
{
return mBrowserWindow->SetVisibility(aVisibility);
if ((mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) && !mChromeLoaded) {
// suppress showing the window until the chrome has completely loaded
return NS_OK;
} else
return mBrowserWindow->SetVisibility(aVisibility);
}
NS_IMETHODIMP nsWebBrowserChrome::SetFocus()
@ -606,4 +666,19 @@ void nsWebBrowserChrome::OnWindowActivityFinished()
if(mBrowserWindow->mThrobber)
mBrowserWindow->mThrobber->Stop();
if (!mSizeSet && (mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) {
nsCOMPtr<nsIDOMWindow> contentWin;
mBrowserWindow->mWebBrowser->GetContentDOMWindow(getter_AddRefs(contentWin));
if (contentWin)
contentWin->SizeToContent();
mBrowserWindow->SetVisibility(PR_TRUE);
mChromeLoaded = PR_TRUE;
}
}
void nsWebBrowserChrome::EnableParent(PRBool aEnable)
{
nsCOMPtr<nsIWidget> parentWidget = mBrowserWindow->mWindow;
if (parentWidget)
parentWidget->Enable(aEnable);
}

View File

@ -18,6 +18,7 @@
*
* Contributor(s):
* Travis Bogard <travis@netscape.com>
* Brian Ryner <bryner@netscape.com>
*/
#ifndef nsWebBrowserChrome_h__
@ -74,11 +75,20 @@ protected:
void OnWindowActivityStart();
void OnWindowActivityFinished();
void EnableParent(PRBool aEnable);
protected:
nsBrowserWindow* mBrowserWindow;
PRBool mTimerSet;
PRPackedBool mTimerSet;
PRPackedBool mContinueModalLoop;
PRPackedBool mSizeSet;
PRPackedBool mChromeLoaded;
PRUint32 mChromeFlags;
MOZ_TIMER_DECLARE(mTotalTime)
nsresult mModalStatus;
PRInt32 mActiveDocuments;
PRInt32 mCurrent, mTotal, mProgress, mMaxProgress;

View File

@ -29,7 +29,6 @@
struct nsRect;
class nsIFileWidget;
class nsIAppShell;
class nsIButton;
class nsIEventListener;

View File

@ -93,7 +93,7 @@ nsNativeBrowserWindow::GetMenuBarHeight(PRInt32 * aHeightOut)
*aHeightOut = 0;
if (nsnull != sgHackMenuBar)
if (nsnull != sgHackMenuBar && mHaveMenuBar)
{
*aHeightOut = sgHackMenuBar->allocation.height;
}