/* -*- 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) 2001 * 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 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 ***** */ /* PromptService is intended to override the default Mozilla PromptService, giving nsIPrompt implementations of our own design, rather than using Mozilla's. Do this by building this into a component and registering the factory with the same CID/ContractID as Mozilla's (see MfcEmbed.cpp). */ #include "stdafx.h" #include "Dialogs.h" #include "PromptService.h" #include "nsCOMPtr.h" #include "nsMemory.h" #include "nsString.h" #include "nsReadableUtils.h" #include "nsIDOMWindow.h" #include "nsIEmbeddingSiteWindow.h" #include "nsIFactory.h" #include "nsIPromptService.h" #include "nsIServiceManager.h" #include "nsIWebBrowserChrome.h" #include "nsIWindowWatcher.h" static HINSTANCE gInstance; //***************************************************************************** // ResourceState //***************************************************************************** class ResourceState { public: ResourceState() { mPreviousInstance = ::AfxGetResourceHandle(); ::AfxSetResourceHandle(gInstance); } ~ResourceState() { ::AfxSetResourceHandle(mPreviousInstance); } private: HINSTANCE mPreviousInstance; }; //***************************************************************************** // CPromptService //***************************************************************************** class CPromptService: public nsIPromptService { public: CPromptService(); virtual ~CPromptService(); NS_DECL_ISUPPORTS NS_DECL_NSIPROMPTSERVICE private: nsCOMPtr mWWatch; CWnd *CWndForDOMWindow(nsIDOMWindow *aWindow); }; //***************************************************************************** NS_IMPL_ISUPPORTS1(CPromptService, nsIPromptService) CPromptService::CPromptService() : mWWatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)) { } CPromptService::~CPromptService() { } CWnd * CPromptService::CWndForDOMWindow(nsIDOMWindow *aWindow) { nsCOMPtr chrome; CWnd *val = 0; if (mWWatch) { nsCOMPtr fosterParent; if (!aWindow) { // it will be a dependent window. try to find a foster parent. mWWatch->GetActiveWindow(getter_AddRefs(fosterParent)); aWindow = fosterParent; } mWWatch->GetChromeForWindow(aWindow, getter_AddRefs(chrome)); } if (chrome) { nsCOMPtr site(do_QueryInterface(chrome)); if (site) { HWND w; site->GetSiteWindow(reinterpret_cast(&w)); val = CWnd::FromHandle(w); } } return val; } NS_IMETHODIMP CPromptService::Alert(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text) { USES_CONVERSION; CWnd *wnd = CWndForDOMWindow(parent); if (wnd) wnd->MessageBox(W2T(text), W2T(dialogTitle), MB_OK | MB_ICONEXCLAMATION); else ::MessageBox(0, W2T(text), W2T(dialogTitle), MB_OK | MB_ICONEXCLAMATION); return NS_OK; } NS_IMETHODIMP CPromptService::AlertCheck(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, const PRUnichar *checkboxMsg, PRBool *checkValue) { ResourceState setState; USES_CONVERSION; CWnd *wnd = CWndForDOMWindow(parent); CAlertCheckDialog dlg(wnd, W2T(dialogTitle), W2T(text), W2T(checkboxMsg), checkValue ? *checkValue : 0); dlg.DoModal(); *checkValue = dlg.m_bCheckBoxValue; return NS_OK; } NS_IMETHODIMP CPromptService::Confirm(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, PRBool *_retval) { USES_CONVERSION; CWnd *wnd = CWndForDOMWindow(parent); int choice; if (wnd) choice = wnd->MessageBox(W2T(text), W2T(dialogTitle), MB_YESNO | MB_ICONEXCLAMATION); else choice = ::MessageBox(0, W2T(text), W2T(dialogTitle), MB_YESNO | MB_ICONEXCLAMATION); *_retval = choice == IDYES ? PR_TRUE : PR_FALSE; return NS_OK; } NS_IMETHODIMP CPromptService::ConfirmCheck(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, const PRUnichar *checkboxMsg, PRBool *checkValue, PRBool *_retval) { ResourceState setState; USES_CONVERSION; CWnd *wnd = CWndForDOMWindow(parent); CConfirmCheckDialog dlg(wnd, W2T(dialogTitle), W2T(text), W2T(checkboxMsg), checkValue ? *checkValue : 0, "Yes", "No", NULL); int iBtnClicked = dlg.DoModal(); *checkValue = dlg.m_bCheckBoxValue; *_retval = iBtnClicked == 0 ? PR_TRUE : PR_FALSE; return NS_OK; } NS_IMETHODIMP CPromptService::Prompt(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, PRUnichar **value, const PRUnichar *checkboxMsg, PRBool *checkValue, PRBool *_retval) { ResourceState setState; USES_CONVERSION; CWnd *wnd = CWndForDOMWindow(parent); CPromptDialog dlg(wnd, W2T(dialogTitle), W2T(text), text && *text ? W2T(text) : 0, checkValue != nsnull, W2T(checkboxMsg), checkValue ? *checkValue : 0); if(dlg.DoModal() == IDOK) { // Get the value entered in the editbox of the PromptDlg if (value && *value) { nsMemory::Free(*value); *value = nsnull; } nsString csPromptEditValue; csPromptEditValue.AssignWithConversion(dlg.m_csPromptAnswer.GetBuffer(0)); *value = ToNewUnicode(csPromptEditValue); *_retval = PR_TRUE; } else *_retval = PR_FALSE; return NS_OK; } NS_IMETHODIMP CPromptService::PromptUsernameAndPassword(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, PRUnichar **username, PRUnichar **password, const PRUnichar *checkboxMsg, PRBool *checkValue, PRBool *_retval) { ResourceState setState; USES_CONVERSION; CWnd *wnd = CWndForDOMWindow(parent); CPromptUsernamePasswordDialog dlg(wnd, W2T(dialogTitle), W2T(text), username && *username ? W2T(*username) : 0, password && *password ? W2T(*password) : 0, checkValue != nsnull, W2T(checkboxMsg), checkValue ? *checkValue : 0); if (dlg.DoModal() == IDOK) { // Get the username entered if (username && *username) { nsMemory::Free(*username); *username = nsnull; } nsString csUserName; csUserName.AssignWithConversion(dlg.m_csUserName.GetBuffer(0)); *username = ToNewUnicode(csUserName); // Get the password entered if (password && *password) { nsMemory::Free(*password); *password = nsnull; } nsString csPassword; csPassword.AssignWithConversion(dlg.m_csPassword.GetBuffer(0)); *password = ToNewUnicode(csPassword); if(checkValue) *checkValue = dlg.m_bCheckBoxValue; *_retval = PR_TRUE; } else *_retval = PR_FALSE; return NS_OK; } NS_IMETHODIMP CPromptService::PromptPassword(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, PRUnichar **password, const PRUnichar *checkboxMsg, PRBool *checkValue, PRBool *_retval) { ResourceState setState; USES_CONVERSION; CWnd *wnd = CWndForDOMWindow(parent); CPromptPasswordDialog dlg(wnd, W2T(dialogTitle), W2T(text), password && *password ? W2T(*password) : 0, checkValue != nsnull, W2T(checkboxMsg), checkValue ? *checkValue : 0); if(dlg.DoModal() == IDOK) { // Get the password entered if (password && *password) { nsMemory::Free(*password); *password = nsnull; } nsString csPassword; csPassword.AssignWithConversion(dlg.m_csPassword.GetBuffer(0)); *password = ToNewUnicode(csPassword); if(checkValue) *checkValue = dlg.m_bCheckBoxValue; *_retval = PR_TRUE; } else *_retval = PR_FALSE; return NS_OK; } NS_IMETHODIMP CPromptService::Select(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, PRUint32 count, const PRUnichar **selectList, PRInt32 *outSelection, PRBool *_retval) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP CPromptService::ConfirmEx(nsIDOMWindow *parent, const PRUnichar *dialogTitle, const PRUnichar *text, PRUint32 buttonFlags, const PRUnichar *button0Title, const PRUnichar *button1Title, const PRUnichar *button2Title, const PRUnichar *checkMsg, PRBool *checkValue, PRInt32 *buttonPressed) { ResourceState setState; USES_CONVERSION; // First, determine the button titles based on buttonFlags const PRUnichar* buttonStrings[] = { button0Title, button1Title, button2Title }; CString csBtnTitles[3]; for(int i=0; i<3; i++) { switch(buttonFlags & 0xff) { case BUTTON_TITLE_OK: csBtnTitles[i] = "Ok"; break; case BUTTON_TITLE_CANCEL: csBtnTitles[i] = "Cancel"; break; case BUTTON_TITLE_YES: csBtnTitles[i] = "Yes"; break; case BUTTON_TITLE_NO: csBtnTitles[i] = "No"; break; case BUTTON_TITLE_SAVE: csBtnTitles[i] = "Save"; break; case BUTTON_TITLE_DONT_SAVE: csBtnTitles[i] = "DontSave"; break; case BUTTON_TITLE_REVERT: csBtnTitles[i] = "Revert"; break; case BUTTON_TITLE_IS_STRING: csBtnTitles[i] = W2T(buttonStrings[i]); break; } buttonFlags >>= 8; } CWnd *wnd = CWndForDOMWindow(parent); CConfirmCheckDialog dlg(wnd, W2T(dialogTitle), W2T(text), checkMsg ? W2T(checkMsg) : NULL, checkValue ? *checkValue : 0, csBtnTitles[0].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[0], csBtnTitles[1].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[1], csBtnTitles[2].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[2]); *buttonPressed = dlg.DoModal(); if(checkValue) *checkValue = dlg.m_bCheckBoxValue; return NS_OK; } //***************************************************************************** // CPromptServiceFactory //***************************************************************************** class CPromptServiceFactory : public nsIFactory { public: NS_DECL_ISUPPORTS NS_DECL_NSIFACTORY CPromptServiceFactory(); virtual ~CPromptServiceFactory(); }; //***************************************************************************** NS_IMPL_ISUPPORTS1(CPromptServiceFactory, nsIFactory) CPromptServiceFactory::CPromptServiceFactory() { } CPromptServiceFactory::~CPromptServiceFactory() { } NS_IMETHODIMP CPromptServiceFactory::CreateInstance(nsISupports *aOuter, const nsIID & aIID, void **aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = NULL; CPromptService *inst = new CPromptService; if (!inst) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = inst->QueryInterface(aIID, aResult); if (rv != NS_OK) { // We didn't get the right interface, so clean up delete inst; } return rv; } NS_IMETHODIMP CPromptServiceFactory::LockFactory(PRBool lock) { return NS_OK; } //***************************************************************************** void InitPromptService(HINSTANCE instance) { gInstance = instance; } nsresult NS_NewPromptServiceFactory(nsIFactory** aFactory) { NS_ENSURE_ARG_POINTER(aFactory); *aFactory = nsnull; CPromptServiceFactory *result = new CPromptServiceFactory; if (!result) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(result); *aFactory = result; return NS_OK; }