/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * 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 Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Pierre Phaneuf */ #include "nsIDOMWindow.h" #include "nsCommonDialogs.h" #include "nsCOMPtr.h" #include "nsIScriptGlobalObject.h" #include "nsXPComFactory.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" static NS_DEFINE_CID( kDialogParamBlockCID, NS_DialogParamBlock_CID); const char* kPromptURL="chrome://global/content/commonDialog.xul"; const char* kQuestionIconURL ="chrome://global/skin/question-icon.gif"; const char* kAlertIconURL ="chrome://global/skin/alert-icon.gif"; const char* kWarningIconURL ="chrome://global/skin/message-icon.gif"; nsCommonDialogs::nsCommonDialogs() { NS_INIT_REFCNT(); } nsCommonDialogs::~nsCommonDialogs() { } NS_IMETHODIMP nsCommonDialogs::Alert(nsIDOMWindow *inParent, const PRUnichar *inWindowTitle, const PRUnichar *inMsg) { nsresult rv; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; // Stuff in Parameters block->SetInt( eNumberButtons, 1 ); block->SetString( eMsg, inMsg ); block->SetString( eDialogTitle,inWindowTitle ); nsString url( kAlertIconURL ); block->SetString( eIconURL, url.GetUnicode()); rv = DoDialog( inParent, block, kPromptURL ); NS_IF_RELEASE( block ); return rv; } NS_IMETHODIMP nsCommonDialogs::AlertCheck(nsIDOMWindow *inParent, const PRUnichar *inWindowTitle,const PRUnichar *inMsg, const PRUnichar *inCheckMsg, PRBool *outCheckValue) { nsresult rv; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; // Stuff in Parameters block->SetInt( eNumberButtons,1 ); block->SetString( eMsg, inMsg ); block->SetString( eDialogTitle, inWindowTitle ); nsString url( kAlertIconURL ); block->SetString( eIconURL, url.GetUnicode()); block->SetString( eCheckboxMsg, inCheckMsg ); block->SetInt(eCheckboxState, *outCheckValue ); rv = DoDialog( inParent, block, kPromptURL ); block->GetInt(eCheckboxState, outCheckValue ); NS_IF_RELEASE( block ); return rv; } NS_IMETHODIMP nsCommonDialogs::Confirm(nsIDOMWindow *inParent, const PRUnichar *inWindowTitle, const PRUnichar *inMsg, PRBool *_retval) { nsresult rv; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; // Stuff in Parameters block->SetInt( eNumberButtons,2 ); block->SetString( eMsg, inMsg ); block->SetString( eDialogTitle, inWindowTitle ); nsString url( kQuestionIconURL ); block->SetString( eIconURL, url.GetUnicode()); rv = DoDialog( inParent, block, kPromptURL ); PRInt32 buttonPressed = 0; block->GetInt( eButtonPressed, &buttonPressed ); *_retval = buttonPressed ? PR_FALSE : PR_TRUE; NS_IF_RELEASE( block ); return rv; } NS_IMETHODIMP nsCommonDialogs::ConfirmCheck(nsIDOMWindow *inParent, const PRUnichar *inWindowTitle,const PRUnichar *inMsg, const PRUnichar *inCheckMsg, PRBool *outCheckValue, PRBool *_retval) { nsresult rv; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; // Stuff in Parameters block->SetInt( eNumberButtons,2 ); block->SetString( eMsg, inMsg ); block->SetString( eDialogTitle, inWindowTitle ); nsString url( kQuestionIconURL ); block->SetString( eIconURL, url.GetUnicode()); block->SetString( eCheckboxMsg, inCheckMsg ); block->SetInt(eCheckboxState, *outCheckValue ); rv = DoDialog( inParent, block, kPromptURL ); PRInt32 tempInt = 0; block->GetInt( eButtonPressed, &tempInt ); *_retval = tempInt ? PR_FALSE : PR_TRUE; block->GetInt(eCheckboxState, & tempInt ); *outCheckValue = PRBool( tempInt ); NS_IF_RELEASE( block ); return rv; } /* Note: It would be nice if someone someday converts all the other dialogs so that they all call UniversalDialog rather than calling on DoDialog directly. This should save a few bytes of memory */ NS_IMETHODIMP nsCommonDialogs::UniversalDialog (nsIDOMWindow *inParent, const PRUnichar *inTitleMessage, const PRUnichar *inDialogTitle, /* e.g., alert, confirm, prompt, prompt password */ const PRUnichar *inMsg, /* main message for dialog */ const PRUnichar *inCheckboxMsg, /* message for checkbox */ const PRUnichar *inButton0Text, /* text for first button */ const PRUnichar *inButton1Text, /* text for second button */ const PRUnichar *inButton2Text, /* text for third button */ const PRUnichar *inButton3Text, /* text for fourth button */ const PRUnichar *inEditfield1Msg, /*message for first edit field */ const PRUnichar *inEditfield2Msg, /* message for second edit field */ PRUnichar **inoutEditfield1Value, /* initial and final value for first edit field */ PRUnichar **inoutEditfield2Value, /* initial and final value for second edit field */ const PRUnichar *inIConURL, /* url of icon to be displayed in dialog */ /* examples are "chrome://global/skin/question-icon.gif" for question mark, "chrome://global/skin/alert-icon.gif" for exclamation mark */ PRBool *inoutCheckboxState, /* initial and final state of check box */ PRInt32 inNumberButtons, /* total number of buttons (0 to 4) */ PRInt32 inNumberEditfields, /* total number of edit fields (0 to 2) */ PRInt32 inEditField1Password, /* is first edit field a password field */ PRInt32 *outButtonPressed) /* number of button that was pressed (0 to 3) */ { nsresult rv; /* check for at least one button */ if (inNumberButtons < 1) { rv = NS_ERROR_FAILURE; } /* create parameter block */ nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance (kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if (NS_FAILED(rv)) { return rv; } /* load up input parameters */ block->SetString(eTitleMessage, inTitleMessage); block->SetString(eDialogTitle, inDialogTitle); block->SetString(eMsg, inMsg); block->SetString(eCheckboxMsg, inCheckboxMsg); if (inNumberButtons >= 4) { block->SetString(eButton3Text, inButton3Text); } if (inNumberButtons >= 3) { block->SetString(eButton2Text, inButton2Text); } if (inNumberButtons >= 2) { block->SetString(eButton1Text, inButton1Text); } if (inNumberButtons >= 1) { block->SetString(eButton0Text, inButton0Text); } if (inNumberEditfields >= 2) { block->SetString(eEditfield2Msg, inEditfield2Msg); block->SetString(eEditfield2Value, *inoutEditfield2Value); } if (inNumberEditfields >= 1) { block->SetString(eEditfield1Msg, inEditfield1Msg); block->SetString(eEditfield1Value, *inoutEditfield1Value); block->SetInt(eEditField1Password, inEditField1Password); } if (inIConURL) { block->SetString(eIconURL, inIConURL); } else { nsString url(kQuestionIconURL); block->SetString(eIconURL, url.GetUnicode()); } if (inCheckboxMsg) { block->SetInt(eCheckboxState, *inoutCheckboxState); } block->SetInt(eNumberButtons, inNumberButtons); block->SetInt(eNumberEditfields, inNumberEditfields); /* perform the dialog */ rv = DoDialog( inParent, block, kPromptURL); /* get back output parameters */ if (outButtonPressed) { block->GetInt(eButtonPressed, outButtonPressed); } if (inCheckboxMsg && inoutCheckboxState) { block->GetInt(eCheckboxState, inoutCheckboxState); } if ((inNumberEditfields >= 2) && inoutEditfield2Value) { block->GetString(eEditfield2Value, inoutEditfield2Value); } if ((inNumberEditfields >= 1) && inoutEditfield1Value) { block->GetString(eEditfield1Value, inoutEditfield1Value); } /* destroy parameter block and return */ NS_IF_RELEASE(block); return rv; } NS_IMETHODIMP nsCommonDialogs::Prompt(nsIDOMWindow *inParent, const PRUnichar *inWindowTitle, const PRUnichar *inMsg, const PRUnichar *inDefaultText, PRUnichar **result, PRBool *_retval) { nsresult rv; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; // Stuff in Parameters block->SetInt( eNumberButtons,2 ); block->SetString( eMsg, inMsg ); block->SetString( eDialogTitle, inWindowTitle ); nsString url( kQuestionIconURL ); block->SetString( eIconURL, url.GetUnicode()); block->SetInt( eNumberEditfields, 1 ); block->SetString( eEditfield1Value, inDefaultText ); rv = DoDialog( inParent, block, kPromptURL ); block->GetString( eEditfield1Value, result ); PRInt32 tempInt = 0; block->GetInt( eButtonPressed, &tempInt ); *_retval = tempInt ? PR_FALSE : PR_TRUE; NS_IF_RELEASE( block ); return rv; } NS_IMETHODIMP nsCommonDialogs::PromptUsernameAndPassword(nsIDOMWindow *inParent, const PRUnichar *inWindowTitle, const PRUnichar *inMsg, PRUnichar **outUser, PRUnichar **outPassword, PRBool *_retval) { nsresult rv; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; // Stuff in Parameters block->SetInt( eNumberButtons,2 ); block->SetString( eMsg, inMsg ); block->SetString( eDialogTitle, inWindowTitle ); nsString url( kQuestionIconURL ); block->SetString( eIconURL, url.GetUnicode()); block->SetInt( eNumberEditfields, 2 ); block->SetString( eEditfield1Value, *outUser ); block->SetString( eEditfield2Value, *outPassword ); rv = DoDialog( inParent, block, kPromptURL ); block->GetString( eEditfield1Value, outUser ); block->GetString( eEditfield2Value, outPassword ); PRInt32 tempInt = 0; block->GetInt( eButtonPressed, &tempInt ); *_retval = tempInt ? PR_FALSE : PR_TRUE; NS_IF_RELEASE( block ); return rv; } NS_IMETHODIMP nsCommonDialogs::PromptPassword(nsIDOMWindow *inParent, const PRUnichar *inWindowTitle, const PRUnichar *inMsg, PRUnichar **outPassword, PRBool *_retval) { nsresult rv; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; // Stuff in Parameters block->SetInt( eNumberButtons,2 ); block->SetString( eMsg, inMsg ); block->SetString( eDialogTitle, inWindowTitle ); nsString url( kQuestionIconURL ); block->SetString( eIconURL, url.GetUnicode()); block->SetInt( eNumberEditfields, 1 ); block->SetInt( eEditField1Password, 1 ); rv = DoDialog( inParent, block, kPromptURL ); block->GetString( eEditfield1Value, outPassword ); PRInt32 tempInt = 0; block->GetInt( eButtonPressed, &tempInt ); *_retval = tempInt ? PR_FALSE : PR_TRUE; NS_IF_RELEASE( block ); return rv; } nsresult nsCommonDialogs::Select(nsIDOMWindow *inParent, const PRUnichar *inDialogTitle, const PRUnichar* inMsg, PRUint32 inCount, const PRUnichar **inList, PRInt32 *outSelection, PRBool *_retval) { nsresult rv; const PRInt32 eSelection = 2 ; nsIDialogParamBlock* block = NULL; rv = nsComponentManager::CreateInstance( kDialogParamBlockCID, 0, NS_GET_IID(nsIDialogParamBlock), (void**)&block ); if ( NS_FAILED( rv ) ) return rv; block->SetNumberStrings( inCount + 2 ); if (inDialogTitle) { block->SetString( 0, inDialogTitle ); } block->SetString(1, inMsg ); block->SetInt( eSelection, inCount ); for ( PRUint32 i = 2; i<= inCount+1; i++ ) { nsAutoString temp(inList[i-2] ); const PRUnichar* text = temp.GetUnicode(); block->SetString( i, text); } *outSelection = -1; static NS_DEFINE_CID( kCommonDialogsCID, NS_CommonDialog_CID ); NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv); if ( NS_SUCCEEDED( rv ) ) { rv = dialog->DoDialog( inParent, block, "chrome://global/content/selectDialog.xul" ); PRInt32 buttonPressed = 0; block->GetInt( nsICommonDialogs::eButtonPressed, &buttonPressed ); block->GetInt( eSelection, outSelection ); *_retval = buttonPressed ? PR_FALSE : PR_TRUE; NS_IF_RELEASE( block ); } return rv; } NS_IMETHODIMP nsCommonDialogs::DoDialog(nsIDOMWindow* inParent, nsIDialogParamBlock *ioParamBlock, const char *inChromeURL) { nsresult rv = NS_OK; if ( inParent && ioParamBlock &&inChromeURL ) { // Get JS context from parent window. nsCOMPtr sgo = do_QueryInterface( inParent, &rv ); if ( NS_SUCCEEDED( rv ) && sgo ) { nsCOMPtr context; sgo->GetContext( getter_AddRefs( context ) ); if ( context ) { JSContext *jsContext = (JSContext*)context->GetNativeContext(); if ( jsContext ) { void *stackPtr; jsval *argv = JS_PushArguments( jsContext, &stackPtr, "sss%ip", inChromeURL, "_blank", "chrome,modal", (const nsIID*)(&NS_GET_IID(nsIDialogParamBlock)), (nsISupports*)ioParamBlock ); if ( argv ) { nsIDOMWindow *newWindow; rv = inParent->OpenDialog( jsContext, argv, 4, &newWindow ); if ( NS_SUCCEEDED( rv ) ) { // newWindow->Release(); } else { } JS_PopArguments( jsContext, stackPtr ); } else { NS_WARNING( "JS_PushArguments failed\n" ); rv = NS_ERROR_FAILURE; } } else { NS_WARNING(" GetNativeContext failed\n" ); rv = NS_ERROR_FAILURE; } } else { NS_WARNING( "GetContext failed\n" ); rv = NS_ERROR_FAILURE; } } else { NS_WARNING( "QueryInterface (for nsIScriptGlobalObject) failed \n" ); } } else { NS_WARNING( " OpenDialogWithArg was passed a null pointer!\n" ); rv = NS_ERROR_NULL_POINTER; } return rv; } NS_IMPL_ADDREF(nsCommonDialogs); NS_IMPL_RELEASE(nsCommonDialogs); NS_IMPL_QUERY_INTERFACE(nsCommonDialogs, NS_GET_IID(nsICommonDialogs));