Back to index

lightning-sunbird  0.9+nobinonly
PromptService.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: Mozilla-sample-code 1.0
00004  *
00005  * Copyright (c) 2002 Netscape Communications Corporation and
00006  * other contributors
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a
00009  * copy of this Mozilla sample software and associated documentation files
00010  * (the "Software"), to deal in the Software without restriction, including
00011  * without limitation the rights to use, copy, modify, merge, publish,
00012  * distribute, sublicense, and/or sell copies of the Software, and to permit
00013  * persons to whom the Software is furnished to do so, subject to the
00014  * following conditions:
00015  *
00016  * The above copyright notice and this permission notice shall be included
00017  * in all copies or substantial portions of the Software.
00018  *
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00020  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00022  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00024  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00025  * DEALINGS IN THE SOFTWARE.
00026  *
00027  * Contributor(s):
00028  *
00029  * ***** END LICENSE BLOCK ***** */
00030 
00031 /* PromptService is intended to override the default Mozilla PromptService,
00032    giving nsIPrompt implementations of our own design, rather than using
00033    Mozilla's. Do this by building this into a component and registering the
00034    factory with the same CID/ContractID as Mozilla's (see MfcEmbed.cpp).
00035 */
00036 
00037 #include "stdafx.h"
00038 #include "Dialogs.h"
00039 #include "PromptService.h"
00040 #include "nsCOMPtr.h"
00041 #include "nsMemory.h"
00042 #include "nsString.h"
00043 #include "nsReadableUtils.h"
00044 #include "nsIDOMWindow.h"
00045 #include "nsIEmbeddingSiteWindow.h"
00046 #include "nsIFactory.h"
00047 #include "nsIPromptService.h"
00048 #include "nsIServiceManager.h"
00049 #include "nsIWebBrowserChrome.h"
00050 #include "nsIWindowWatcher.h"
00051 
00052 static HINSTANCE gInstance;
00053 
00054 //*****************************************************************************
00055 // ResourceState
00056 //***************************************************************************** 
00057 
00058 class ResourceState {
00059 public:
00060   ResourceState() {
00061     mPreviousInstance = ::AfxGetResourceHandle();
00062     ::AfxSetResourceHandle(gInstance);
00063   }
00064   ~ResourceState() {
00065     ::AfxSetResourceHandle(mPreviousInstance);
00066   }
00067 private:
00068   HINSTANCE mPreviousInstance;
00069 };
00070 
00071 
00072 //*****************************************************************************
00073 // CPromptService
00074 //*****************************************************************************
00075 
00076 class CPromptService: public nsIPromptService {
00077 public:
00078                  CPromptService();
00079   virtual       ~CPromptService();
00080 
00081   NS_DECL_ISUPPORTS
00082   NS_DECL_NSIPROMPTSERVICE
00083 
00084 private:
00085   nsCOMPtr<nsIWindowWatcher> mWWatch;
00086   CWnd *CWndForDOMWindow(nsIDOMWindow *aWindow);
00087 };
00088 
00089 //*****************************************************************************
00090 
00091 NS_IMPL_ISUPPORTS1(CPromptService, nsIPromptService)
00092 
00093 CPromptService::CPromptService() :
00094   mWWatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID))
00095 {
00096 }
00097 
00098 CPromptService::~CPromptService() {
00099 }
00100 
00101 CWnd *
00102 CPromptService::CWndForDOMWindow(nsIDOMWindow *aWindow)
00103 {
00104   nsCOMPtr<nsIWebBrowserChrome> chrome;
00105   CWnd *val = 0;
00106 
00107   if (mWWatch) {
00108     nsCOMPtr<nsIDOMWindow> fosterParent;
00109     if (!aWindow) { // it will be a dependent window. try to find a foster parent.
00110       mWWatch->GetActiveWindow(getter_AddRefs(fosterParent));
00111       aWindow = fosterParent;
00112     }
00113     mWWatch->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
00114   }
00115 
00116   if (chrome) {
00117     nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
00118     if (site) {
00119       HWND w;
00120       site->GetSiteWindow(reinterpret_cast<void **>(&w));
00121       val = CWnd::FromHandle(w);
00122     }
00123   }
00124 
00125   return val;
00126 }
00127 
00128 NS_IMETHODIMP CPromptService::Alert(nsIDOMWindow *parent, const PRUnichar *dialogTitle,
00129                                     const PRUnichar *text)
00130 {
00131   USES_CONVERSION;
00132   CWnd *wnd = CWndForDOMWindow(parent);
00133   if (wnd)
00134     wnd->MessageBox(W2CT(text), W2CT(dialogTitle), MB_OK | MB_ICONEXCLAMATION);
00135   else
00136     ::MessageBox(0, W2CT(text), W2CT(dialogTitle), MB_OK | MB_ICONEXCLAMATION);
00137 
00138   return NS_OK;
00139 }
00140 
00141 NS_IMETHODIMP CPromptService::AlertCheck(nsIDOMWindow *parent,
00142                                          const PRUnichar *dialogTitle,
00143                                          const PRUnichar *text,
00144                                          const PRUnichar *checkboxMsg,
00145                                          PRBool *checkValue)
00146 {
00147   ResourceState setState;
00148   USES_CONVERSION;
00149 
00150   CWnd *wnd = CWndForDOMWindow(parent);
00151   CAlertCheckDialog dlg(wnd, W2CT(dialogTitle), W2CT(text),
00152                     W2CT(checkboxMsg), checkValue ? *checkValue : 0);
00153 
00154   dlg.DoModal();
00155 
00156   *checkValue = dlg.m_bCheckBoxValue;
00157 
00158   return NS_OK;
00159 }
00160 
00161 NS_IMETHODIMP CPromptService::Confirm(nsIDOMWindow *parent,
00162                                       const PRUnichar *dialogTitle,
00163                                       const PRUnichar *text,
00164                                       PRBool *_retval)
00165 {
00166   USES_CONVERSION;
00167   CWnd *wnd = CWndForDOMWindow(parent);
00168   int choice;
00169 
00170   if (wnd)
00171     choice = wnd->MessageBox(W2CT(text), W2CT(dialogTitle),
00172                       MB_YESNO | MB_ICONEXCLAMATION);
00173   else
00174     choice = ::MessageBox(0, W2CT(text), W2CT(dialogTitle),
00175                       MB_YESNO | MB_ICONEXCLAMATION);
00176 
00177   *_retval = choice == IDYES ? PR_TRUE : PR_FALSE;
00178 
00179   return NS_OK;
00180 }
00181 
00182 NS_IMETHODIMP CPromptService::ConfirmCheck(nsIDOMWindow *parent,
00183                                            const PRUnichar *dialogTitle,
00184                                            const PRUnichar *text,
00185                                            const PRUnichar *checkboxMsg,
00186                                            PRBool *checkValue,
00187                                            PRBool *_retval)
00188 {
00189     ResourceState setState;
00190     USES_CONVERSION;
00191 
00192     CWnd *wnd = CWndForDOMWindow(parent);
00193     CConfirmCheckDialog dlg(wnd, W2CT(dialogTitle), W2CT(text),
00194                     W2CT(checkboxMsg), checkValue ? *checkValue : 0,
00195                     _T("Yes"), _T("No"), NULL);
00196 
00197     int iBtnClicked = dlg.DoModal();
00198 
00199     *checkValue = dlg.m_bCheckBoxValue;
00200 
00201     *_retval = iBtnClicked == 0 ? PR_TRUE : PR_FALSE;
00202 
00203     return NS_OK;
00204 }
00205 
00206 NS_IMETHODIMP CPromptService::Prompt(nsIDOMWindow *parent,
00207                                      const PRUnichar *dialogTitle,
00208                                      const PRUnichar *text,
00209                                      PRUnichar **value,
00210                                      const PRUnichar *checkboxMsg,
00211                                      PRBool *checkValue,
00212                                      PRBool *_retval)
00213 {
00214   ResourceState setState;
00215   USES_CONVERSION;
00216 
00217   CWnd *wnd = CWndForDOMWindow(parent);
00218   CPromptDialog dlg(wnd, W2CT(dialogTitle), W2CT(text),
00219                     text && *text ? W2CT(text) : 0,
00220                     checkValue != nsnull, W2CT(checkboxMsg),
00221                     checkValue ? *checkValue : 0);
00222   if(dlg.DoModal() == IDOK) {
00223     // Get the value entered in the editbox of the PromptDlg
00224     if (value && *value) {
00225       nsMemory::Free(*value);
00226       *value = nsnull;
00227     }
00228     USES_CONVERSION;
00229     nsString csPromptEditValue;
00230     csPromptEditValue.Assign(T2CW(dlg.m_csPromptAnswer.GetBuffer(0)));
00231 
00232     *value = ToNewUnicode(csPromptEditValue);
00233 
00234     *_retval = PR_TRUE;
00235   } else
00236     *_retval = PR_FALSE;
00237 
00238   return NS_OK;
00239 }
00240 
00241 NS_IMETHODIMP CPromptService::PromptUsernameAndPassword(nsIDOMWindow *parent,
00242                                                         const PRUnichar *dialogTitle,
00243                                                         const PRUnichar *text,
00244                                                         PRUnichar **username,
00245                                                         PRUnichar **password,
00246                                                         const PRUnichar *checkboxMsg,
00247                                                         PRBool *checkValue,
00248                                                         PRBool *_retval)
00249 {
00250   ResourceState setState;
00251   USES_CONVERSION;
00252 
00253   CWnd *wnd = CWndForDOMWindow(parent);
00254   CPromptUsernamePasswordDialog dlg(wnd, W2CT(dialogTitle), W2CT(text),
00255                     username && *username ? W2CT(*username) : 0,
00256                     password && *password ? W2CT(*password) : 0, 
00257                     checkValue != nsnull, W2CT(checkboxMsg),
00258                     checkValue ? *checkValue : 0);
00259 
00260   if (dlg.DoModal() == IDOK) {
00261     // Get the username entered
00262     if (username && *username) {
00263         nsMemory::Free(*username);
00264         *username = nsnull;
00265     }
00266     USES_CONVERSION;
00267     nsString csUserName;
00268     csUserName.Assign(T2CW(dlg.m_csUserName.GetBuffer(0)));
00269     *username = ToNewUnicode(csUserName);
00270 
00271     // Get the password entered
00272     if (password && *password) {
00273       nsMemory::Free(*password);
00274       *password = nsnull;
00275     }
00276     nsString csPassword;
00277     csPassword.Assign(T2CW(dlg.m_csPassword.GetBuffer(0)));
00278     *password = ToNewUnicode(csPassword);
00279 
00280     if(checkValue)          
00281       *checkValue = dlg.m_bCheckBoxValue;
00282 
00283     *_retval = PR_TRUE;
00284   } else
00285     *_retval = PR_FALSE;
00286 
00287   return NS_OK;
00288 }
00289 
00290 NS_IMETHODIMP CPromptService::PromptPassword(nsIDOMWindow *parent,
00291                                              const PRUnichar *dialogTitle,
00292                                              const PRUnichar *text,
00293                                              PRUnichar **password,
00294                                              const PRUnichar *checkboxMsg,
00295                                              PRBool *checkValue,
00296                                              PRBool *_retval)
00297 {
00298   ResourceState setState;
00299   USES_CONVERSION;
00300 
00301   CWnd *wnd = CWndForDOMWindow(parent);
00302   CPromptPasswordDialog dlg(wnd, W2CT(dialogTitle), W2CT(text),
00303                             password && *password ? W2CT(*password) : 0,
00304                             checkValue != nsnull, W2CT(checkboxMsg),
00305                             checkValue ? *checkValue : 0);
00306   if(dlg.DoModal() == IDOK) {
00307     // Get the password entered
00308     if (password && *password) {
00309         nsMemory::Free(*password);
00310         *password = nsnull;
00311     }
00312     USES_CONVERSION;
00313     nsString csPassword;
00314     csPassword.Assign(T2CW(dlg.m_csPassword.GetBuffer(0)));
00315     *password = ToNewUnicode(csPassword);
00316 
00317     if(checkValue)
00318       *checkValue = dlg.m_bCheckBoxValue;
00319 
00320     *_retval = PR_TRUE;
00321   } else
00322     *_retval = PR_FALSE;
00323 
00324   return NS_OK;
00325 }
00326 
00327 NS_IMETHODIMP CPromptService::Select(nsIDOMWindow *parent,
00328                                      const PRUnichar *dialogTitle,
00329                                      const PRUnichar *text, PRUint32 count,
00330                                      const PRUnichar **selectList,
00331                                      PRInt32 *outSelection,
00332                                      PRBool *_retval)
00333 {
00334   return NS_ERROR_NOT_IMPLEMENTED;
00335 }
00336 
00337 NS_IMETHODIMP CPromptService::ConfirmEx(nsIDOMWindow *parent,
00338                                         const PRUnichar *dialogTitle,
00339                                         const PRUnichar *text,
00340                                         PRUint32 buttonFlags,
00341                                         const PRUnichar *button0Title,
00342                                         const PRUnichar *button1Title,
00343                                         const PRUnichar *button2Title,
00344                                         const PRUnichar *checkMsg,
00345                                         PRBool *checkValue,
00346                                         PRInt32 *buttonPressed)
00347 {
00348     ResourceState setState;
00349     USES_CONVERSION;
00350 
00351     // First, determine the button titles based on buttonFlags
00352     const PRUnichar* buttonStrings[] = { button0Title, button1Title, button2Title };
00353     CString csBtnTitles[3];
00354 
00355     for(int i=0; i<3; i++)
00356     {
00357         switch(buttonFlags & 0xff) {
00358             case BUTTON_TITLE_OK:
00359                 csBtnTitles[i] = "Ok";
00360                 break;
00361             case BUTTON_TITLE_CANCEL:
00362                 csBtnTitles[i] = "Cancel";
00363                 break;
00364             case BUTTON_TITLE_YES:
00365                 csBtnTitles[i] = "Yes";
00366                 break;
00367             case BUTTON_TITLE_NO:
00368                 csBtnTitles[i] = "No";
00369                 break;
00370             case BUTTON_TITLE_SAVE:
00371                 csBtnTitles[i] = "Save";
00372                 break;
00373             case BUTTON_TITLE_DONT_SAVE:
00374                 csBtnTitles[i] = "DontSave";
00375                 break;
00376             case BUTTON_TITLE_REVERT:
00377                 csBtnTitles[i] = "Revert";
00378                 break;
00379             case BUTTON_TITLE_IS_STRING:
00380                 csBtnTitles[i] = W2CT(buttonStrings[i]);
00381                 break;
00382         }
00383    
00384         buttonFlags >>= 8;    
00385     }
00386 
00387     CWnd *wnd = CWndForDOMWindow(parent);
00388     CConfirmCheckDialog dlg(wnd, W2CT(dialogTitle), W2CT(text),
00389         checkMsg ? W2CT(checkMsg) : NULL, checkValue ? *checkValue : 0,
00390                     csBtnTitles[0].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[0], 
00391                     csBtnTitles[1].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[1], 
00392                     csBtnTitles[2].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[2]);
00393 
00394     *buttonPressed = dlg.DoModal();
00395 
00396     if(checkValue)
00397         *checkValue = dlg.m_bCheckBoxValue;
00398 
00399     return NS_OK;    
00400 }
00401  
00402 //*****************************************************************************
00403 // CPromptServiceFactory
00404 //*****************************************************************************   
00405 
00406 class CPromptServiceFactory : public nsIFactory {
00407 public:
00408   NS_DECL_ISUPPORTS
00409   NS_DECL_NSIFACTORY
00410 
00411   CPromptServiceFactory();
00412   virtual ~CPromptServiceFactory();
00413 };
00414 
00415 //*****************************************************************************
00416 
00417 NS_IMPL_ISUPPORTS1(CPromptServiceFactory, nsIFactory)
00418 
00419 CPromptServiceFactory::CPromptServiceFactory() {
00420 }
00421 
00422 CPromptServiceFactory::~CPromptServiceFactory() {
00423 }
00424 
00425 NS_IMETHODIMP CPromptServiceFactory::CreateInstance(nsISupports *aOuter, const nsIID & aIID, void **aResult)
00426 {
00427   NS_ENSURE_ARG_POINTER(aResult);
00428   
00429   *aResult = NULL;  
00430   CPromptService *inst = new CPromptService;    
00431   if (!inst)
00432     return NS_ERROR_OUT_OF_MEMORY;
00433     
00434   nsresult rv = inst->QueryInterface(aIID, aResult);
00435   if (rv != NS_OK) {  
00436     // We didn't get the right interface, so clean up  
00437     delete inst;  
00438   }  
00439     
00440   return rv;
00441 }
00442 
00443 NS_IMETHODIMP CPromptServiceFactory::LockFactory(PRBool lock)
00444 {
00445   return NS_OK;
00446 }
00447 
00448 //*****************************************************************************
00449 
00450 void InitPromptService(HINSTANCE instance) {
00451 
00452   gInstance = instance;
00453 }
00454 
00455 nsresult NS_NewPromptServiceFactory(nsIFactory** aFactory)
00456 {
00457   NS_ENSURE_ARG_POINTER(aFactory);
00458   *aFactory = nsnull;
00459   
00460   CPromptServiceFactory *result = new CPromptServiceFactory;
00461   if (!result)
00462     return NS_ERROR_OUT_OF_MEMORY;
00463     
00464   NS_ADDREF(result);
00465   *aFactory = result;
00466   
00467   return NS_OK;
00468 }