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: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org Code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* PromptService is intended to override the default Mozilla PromptService,
00039    giving nsIPrompt implementations of our own design, rather than using
00040    Mozilla's. Do this by building this into a component and registering the
00041    factory with the same CID/ContractID as Mozilla's (see MfcEmbed.cpp).
00042 */
00043 
00044 #include "stdafx.h"
00045 #include "Dialogs.h"
00046 #include "PromptService.h"
00047 #include "nsCOMPtr.h"
00048 #include "nsMemory.h"
00049 #include "nsString.h"
00050 #include "nsReadableUtils.h"
00051 #include "nsIDOMWindow.h"
00052 #include "nsIEmbeddingSiteWindow.h"
00053 #include "nsIFactory.h"
00054 #include "nsIPromptService.h"
00055 #include "nsIServiceManager.h"
00056 #include "nsIWebBrowserChrome.h"
00057 #include "nsIWindowWatcher.h"
00058 
00059 static HINSTANCE gInstance;
00060 
00061 //*****************************************************************************
00062 // ResourceState
00063 //***************************************************************************** 
00064 
00065 class ResourceState {
00066 public:
00067   ResourceState() {
00068     mPreviousInstance = ::AfxGetResourceHandle();
00069     ::AfxSetResourceHandle(gInstance);
00070   }
00071   ~ResourceState() {
00072     ::AfxSetResourceHandle(mPreviousInstance);
00073   }
00074 private:
00075   HINSTANCE mPreviousInstance;
00076 };
00077 
00078 
00079 //*****************************************************************************
00080 // CPromptService
00081 //*****************************************************************************
00082 
00083 class CPromptService: public nsIPromptService {
00084 public:
00085                  CPromptService();
00086   virtual       ~CPromptService();
00087 
00088   NS_DECL_ISUPPORTS
00089   NS_DECL_NSIPROMPTSERVICE
00090 
00091 private:
00092   nsCOMPtr<nsIWindowWatcher> mWWatch;
00093   CWnd *CWndForDOMWindow(nsIDOMWindow *aWindow);
00094 };
00095 
00096 //*****************************************************************************
00097 
00098 NS_IMPL_ISUPPORTS1(CPromptService, nsIPromptService)
00099 
00100 CPromptService::CPromptService() :
00101   mWWatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID))
00102 {
00103 }
00104 
00105 CPromptService::~CPromptService() {
00106 }
00107 
00108 CWnd *
00109 CPromptService::CWndForDOMWindow(nsIDOMWindow *aWindow)
00110 {
00111   nsCOMPtr<nsIWebBrowserChrome> chrome;
00112   CWnd *val = 0;
00113 
00114   if (mWWatch) {
00115     nsCOMPtr<nsIDOMWindow> fosterParent;
00116     if (!aWindow) { // it will be a dependent window. try to find a foster parent.
00117       mWWatch->GetActiveWindow(getter_AddRefs(fosterParent));
00118       aWindow = fosterParent;
00119     }
00120     mWWatch->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
00121   }
00122 
00123   if (chrome) {
00124     nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
00125     if (site) {
00126       HWND w;
00127       site->GetSiteWindow(reinterpret_cast<void **>(&w));
00128       val = CWnd::FromHandle(w);
00129     }
00130   }
00131 
00132   return val;
00133 }
00134 
00135 NS_IMETHODIMP CPromptService::Alert(nsIDOMWindow *parent, const PRUnichar *dialogTitle,
00136                                     const PRUnichar *text)
00137 {
00138   USES_CONVERSION;
00139   CWnd *wnd = CWndForDOMWindow(parent);
00140   if (wnd)
00141     wnd->MessageBox(W2T(text), W2T(dialogTitle), MB_OK | MB_ICONEXCLAMATION);
00142   else
00143     ::MessageBox(0, W2T(text), W2T(dialogTitle), MB_OK | MB_ICONEXCLAMATION);
00144 
00145   return NS_OK;
00146 }
00147 
00148 NS_IMETHODIMP CPromptService::AlertCheck(nsIDOMWindow *parent,
00149                                          const PRUnichar *dialogTitle,
00150                                          const PRUnichar *text,
00151                                          const PRUnichar *checkboxMsg,
00152                                          PRBool *checkValue)
00153 {
00154   ResourceState setState;
00155   USES_CONVERSION;
00156 
00157   CWnd *wnd = CWndForDOMWindow(parent);
00158   CAlertCheckDialog dlg(wnd, W2T(dialogTitle), W2T(text),
00159                     W2T(checkboxMsg), checkValue ? *checkValue : 0);
00160 
00161   dlg.DoModal();
00162 
00163   *checkValue = dlg.m_bCheckBoxValue;
00164 
00165   return NS_OK;
00166 }
00167 
00168 NS_IMETHODIMP CPromptService::Confirm(nsIDOMWindow *parent,
00169                                       const PRUnichar *dialogTitle,
00170                                       const PRUnichar *text,
00171                                       PRBool *_retval)
00172 {
00173   USES_CONVERSION;
00174   CWnd *wnd = CWndForDOMWindow(parent);
00175   int choice;
00176 
00177   if (wnd)
00178     choice = wnd->MessageBox(W2T(text), W2T(dialogTitle),
00179                       MB_YESNO | MB_ICONEXCLAMATION);
00180   else
00181     choice = ::MessageBox(0, W2T(text), W2T(dialogTitle),
00182                       MB_YESNO | MB_ICONEXCLAMATION);
00183 
00184   *_retval = choice == IDYES ? PR_TRUE : PR_FALSE;
00185 
00186   return NS_OK;
00187 }
00188 
00189 NS_IMETHODIMP CPromptService::ConfirmCheck(nsIDOMWindow *parent,
00190                                            const PRUnichar *dialogTitle,
00191                                            const PRUnichar *text,
00192                                            const PRUnichar *checkboxMsg,
00193                                            PRBool *checkValue,
00194                                            PRBool *_retval)
00195 {
00196     ResourceState setState;
00197     USES_CONVERSION;
00198 
00199     CWnd *wnd = CWndForDOMWindow(parent);
00200     CConfirmCheckDialog dlg(wnd, W2T(dialogTitle), W2T(text),
00201                     W2T(checkboxMsg), checkValue ? *checkValue : 0,
00202                     "Yes", "No", NULL);
00203 
00204     int iBtnClicked = dlg.DoModal();
00205 
00206     *checkValue = dlg.m_bCheckBoxValue;
00207 
00208     *_retval = iBtnClicked == 0 ? PR_TRUE : PR_FALSE;
00209 
00210     return NS_OK;
00211 }
00212 
00213 NS_IMETHODIMP CPromptService::Prompt(nsIDOMWindow *parent,
00214                                      const PRUnichar *dialogTitle,
00215                                      const PRUnichar *text,
00216                                      PRUnichar **value,
00217                                      const PRUnichar *checkboxMsg,
00218                                      PRBool *checkValue,
00219                                      PRBool *_retval)
00220 {
00221   ResourceState setState;
00222   USES_CONVERSION;
00223 
00224   CWnd *wnd = CWndForDOMWindow(parent);
00225   CPromptDialog dlg(wnd, W2T(dialogTitle), W2T(text),
00226                     text && *text ? W2T(text) : 0,
00227                     checkValue != nsnull, W2T(checkboxMsg),
00228                     checkValue ? *checkValue : 0);
00229   if(dlg.DoModal() == IDOK) {
00230     // Get the value entered in the editbox of the PromptDlg
00231     if (value && *value) {
00232       nsMemory::Free(*value);
00233       *value = nsnull;
00234     }
00235     nsString csPromptEditValue;
00236     csPromptEditValue.AssignWithConversion(dlg.m_csPromptAnswer.GetBuffer(0));
00237 
00238     *value = ToNewUnicode(csPromptEditValue);
00239 
00240     *_retval = PR_TRUE;
00241   } else
00242     *_retval = PR_FALSE;
00243 
00244   return NS_OK;
00245 }
00246 
00247 NS_IMETHODIMP CPromptService::PromptUsernameAndPassword(nsIDOMWindow *parent,
00248                                                         const PRUnichar *dialogTitle,
00249                                                         const PRUnichar *text,
00250                                                         PRUnichar **username,
00251                                                         PRUnichar **password,
00252                                                         const PRUnichar *checkboxMsg,
00253                                                         PRBool *checkValue,
00254                                                         PRBool *_retval)
00255 {
00256   ResourceState setState;
00257   USES_CONVERSION;
00258 
00259   CWnd *wnd = CWndForDOMWindow(parent);
00260   CPromptUsernamePasswordDialog dlg(wnd, W2T(dialogTitle), W2T(text),
00261                     username && *username ? W2T(*username) : 0,
00262                     password && *password ? W2T(*password) : 0, 
00263                     checkValue != nsnull, W2T(checkboxMsg),
00264                     checkValue ? *checkValue : 0);
00265 
00266   if (dlg.DoModal() == IDOK) {
00267     // Get the username entered
00268     if (username && *username) {
00269         nsMemory::Free(*username);
00270         *username = nsnull;
00271     }
00272     nsString csUserName;
00273     csUserName.AssignWithConversion(dlg.m_csUserName.GetBuffer(0));
00274     *username = ToNewUnicode(csUserName);
00275 
00276     // Get the password entered
00277     if (password && *password) {
00278       nsMemory::Free(*password);
00279       *password = nsnull;
00280     }
00281     nsString csPassword;
00282     csPassword.AssignWithConversion(dlg.m_csPassword.GetBuffer(0));
00283     *password = ToNewUnicode(csPassword);
00284 
00285     if(checkValue)          
00286       *checkValue = dlg.m_bCheckBoxValue;
00287 
00288     *_retval = PR_TRUE;
00289   } else
00290     *_retval = PR_FALSE;
00291 
00292   return NS_OK;
00293 }
00294 
00295 NS_IMETHODIMP CPromptService::PromptPassword(nsIDOMWindow *parent,
00296                                              const PRUnichar *dialogTitle,
00297                                              const PRUnichar *text,
00298                                              PRUnichar **password,
00299                                              const PRUnichar *checkboxMsg,
00300                                              PRBool *checkValue,
00301                                              PRBool *_retval)
00302 {
00303   ResourceState setState;
00304   USES_CONVERSION;
00305 
00306   CWnd *wnd = CWndForDOMWindow(parent);
00307   CPromptPasswordDialog dlg(wnd, W2T(dialogTitle), W2T(text),
00308                             password && *password ? W2T(*password) : 0,
00309                             checkValue != nsnull, W2T(checkboxMsg),
00310                             checkValue ? *checkValue : 0);
00311   if(dlg.DoModal() == IDOK) {
00312     // Get the password entered
00313     if (password && *password) {
00314         nsMemory::Free(*password);
00315         *password = nsnull;
00316     }
00317     nsString csPassword;
00318     csPassword.AssignWithConversion(dlg.m_csPassword.GetBuffer(0));
00319     *password = ToNewUnicode(csPassword);
00320 
00321     if(checkValue)
00322       *checkValue = dlg.m_bCheckBoxValue;
00323 
00324     *_retval = PR_TRUE;
00325   } else
00326     *_retval = PR_FALSE;
00327 
00328   return NS_OK;
00329 }
00330 
00331 NS_IMETHODIMP CPromptService::Select(nsIDOMWindow *parent,
00332                                      const PRUnichar *dialogTitle,
00333                                      const PRUnichar *text, PRUint32 count,
00334                                      const PRUnichar **selectList,
00335                                      PRInt32 *outSelection,
00336                                      PRBool *_retval)
00337 {
00338   return NS_ERROR_NOT_IMPLEMENTED;
00339 }
00340 
00341 NS_IMETHODIMP CPromptService::ConfirmEx(nsIDOMWindow *parent,
00342                                         const PRUnichar *dialogTitle,
00343                                         const PRUnichar *text,
00344                                         PRUint32 buttonFlags,
00345                                         const PRUnichar *button0Title,
00346                                         const PRUnichar *button1Title,
00347                                         const PRUnichar *button2Title,
00348                                         const PRUnichar *checkMsg,
00349                                         PRBool *checkValue,
00350                                         PRInt32 *buttonPressed)
00351 {
00352     ResourceState setState;
00353     USES_CONVERSION;
00354 
00355     // First, determine the button titles based on buttonFlags
00356     const PRUnichar* buttonStrings[] = { button0Title, button1Title, button2Title };
00357     CString csBtnTitles[3];
00358 
00359     for(int i=0; i<3; i++)
00360     {
00361         switch(buttonFlags & 0xff) {
00362             case BUTTON_TITLE_OK:
00363                 csBtnTitles[i] = "Ok";
00364                 break;
00365             case BUTTON_TITLE_CANCEL:
00366                 csBtnTitles[i] = "Cancel";
00367                 break;
00368             case BUTTON_TITLE_YES:
00369                 csBtnTitles[i] = "Yes";
00370                 break;
00371             case BUTTON_TITLE_NO:
00372                 csBtnTitles[i] = "No";
00373                 break;
00374             case BUTTON_TITLE_SAVE:
00375                 csBtnTitles[i] = "Save";
00376                 break;
00377             case BUTTON_TITLE_DONT_SAVE:
00378                 csBtnTitles[i] = "DontSave";
00379                 break;
00380             case BUTTON_TITLE_REVERT:
00381                 csBtnTitles[i] = "Revert";
00382                 break;
00383             case BUTTON_TITLE_IS_STRING:
00384                 csBtnTitles[i] = W2T(buttonStrings[i]);
00385                 break;
00386         }
00387    
00388         buttonFlags >>= 8;    
00389     }
00390 
00391     CWnd *wnd = CWndForDOMWindow(parent);
00392     CConfirmCheckDialog dlg(wnd, W2T(dialogTitle), W2T(text),
00393         checkMsg ? W2T(checkMsg) : NULL, checkValue ? *checkValue : 0,
00394                     csBtnTitles[0].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[0], 
00395                     csBtnTitles[1].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[1], 
00396                     csBtnTitles[2].IsEmpty() ? NULL : (LPCTSTR)csBtnTitles[2]);
00397 
00398     *buttonPressed = dlg.DoModal();
00399 
00400     if(checkValue)
00401         *checkValue = dlg.m_bCheckBoxValue;
00402 
00403     return NS_OK;    
00404 }
00405  
00406 //*****************************************************************************
00407 // CPromptServiceFactory
00408 //*****************************************************************************   
00409 
00410 class CPromptServiceFactory : public nsIFactory {
00411 public:
00412   NS_DECL_ISUPPORTS
00413   NS_DECL_NSIFACTORY
00414 
00415   CPromptServiceFactory();
00416   virtual ~CPromptServiceFactory();
00417 };
00418 
00419 //*****************************************************************************
00420 
00421 NS_IMPL_ISUPPORTS1(CPromptServiceFactory, nsIFactory)
00422 
00423 CPromptServiceFactory::CPromptServiceFactory() {
00424 }
00425 
00426 CPromptServiceFactory::~CPromptServiceFactory() {
00427 }
00428 
00429 NS_IMETHODIMP CPromptServiceFactory::CreateInstance(nsISupports *aOuter, const nsIID & aIID, void **aResult)
00430 {
00431   NS_ENSURE_ARG_POINTER(aResult);
00432   
00433   *aResult = NULL;  
00434   CPromptService *inst = new CPromptService;    
00435   if (!inst)
00436     return NS_ERROR_OUT_OF_MEMORY;
00437     
00438   nsresult rv = inst->QueryInterface(aIID, aResult);
00439   if (rv != NS_OK) {  
00440     // We didn't get the right interface, so clean up  
00441     delete inst;  
00442   }  
00443     
00444   return rv;
00445 }
00446 
00447 NS_IMETHODIMP CPromptServiceFactory::LockFactory(PRBool lock)
00448 {
00449   return NS_OK;
00450 }
00451 
00452 //*****************************************************************************
00453 
00454 void InitPromptService(HINSTANCE instance) {
00455 
00456   gInstance = instance;
00457 }
00458 
00459 nsresult NS_NewPromptServiceFactory(nsIFactory** aFactory)
00460 {
00461   NS_ENSURE_ARG_POINTER(aFactory);
00462   *aFactory = nsnull;
00463   
00464   CPromptServiceFactory *result = new CPromptServiceFactory;
00465   if (!result)
00466     return NS_ERROR_OUT_OF_MEMORY;
00467     
00468   NS_ADDREF(result);
00469   *aFactory = result;
00470   
00471   return NS_OK;
00472 }