Back to index

lightning-sunbird  0.9+nobinonly
nsCocoaBrowserService.mm
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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) 1998
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 #include "nsCocoaBrowserService.h"
00039 
00040 #include "nsIWindowWatcher.h"
00041 #include "nsIWebBrowserChrome.h"
00042 #include "nsIEmbeddingSiteWindow.h"
00043 #include "nsIProfile.h"
00044 #include "NSBrowserView.h"
00045 #include "nsCRT.h"
00046 #include "nsString.h"
00047 
00048 PRUint32 nsCocoaBrowserService::sNumBrowsers = 0;
00049 nsAlertController* nsCocoaBrowserService::sController = nsnull;
00050 nsCocoaBrowserService* nsCocoaBrowserService::sSingleton = nsnull;
00051 
00052 // nsCocoaBrowserService implementation
00053 nsCocoaBrowserService::nsCocoaBrowserService()
00054 {
00055 }
00056 
00057 nsCocoaBrowserService::~nsCocoaBrowserService()
00058 {
00059   NS_TermEmbedding();
00060 }
00061 
00062 NS_IMPL_ISUPPORTS3(nsCocoaBrowserService,
00063                    nsIWindowCreator,
00064                    nsIPromptService,
00065                    nsIFactory)
00066 
00067 nsresult
00068 nsCocoaBrowserService::InitEmbedding()
00069 {
00070   if (sSingleton) {
00071     sNumBrowsers++;
00072     return NS_OK;
00073   }
00074 
00075   // XXX Temporary hack to make sure we find the 
00076   // right executable directory
00077   NSBundle* mainBundle = [NSBundle mainBundle];
00078   NSString* path = [mainBundle bundlePath];
00079   NSMutableString* mutablePath = [NSMutableString stringWithString:path];
00080   [mutablePath appendString:@"/Contents/MacOS/"];
00081   const char* cstr = [mutablePath cString];
00082   setenv("MOZILLA_FIVE_HOME", cstr, 1);
00083 
00084   sSingleton = new nsCocoaBrowserService();
00085   if (!sSingleton) {
00086     return NS_ERROR_OUT_OF_MEMORY;
00087   }
00088   NS_ADDREF(sSingleton);
00089   sNumBrowsers = 1;
00090 
00091   nsresult rv = NS_InitEmbedding(nsnull, nsnull);
00092   if (NS_FAILED(rv)) {
00093     return rv;
00094   }
00095 
00096   // Register as the prompt service
00097 #define NS_PROMPTSERVICE_CID \
00098      {0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}
00099   static NS_DEFINE_CID(kPromptServiceCID, NS_PROMPTSERVICE_CID);
00100 
00101   nsCOMPtr<nsIComponentRegistrar> registrar;
00102   rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
00103   if (NS_FAILED(rv)) {
00104     return rv;
00105   }
00106 
00107   rv = registrar->RegisterFactory(kPromptServiceCID,
00108                                   "Prompt Service",
00109                                   "@mozilla.org/embedcomp/prompt-service;1",
00110                                   sSingleton);
00111   if (NS_FAILED(rv)) {
00112     return rv;
00113   }
00114 
00115   // Register as the window creator
00116   nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
00117   if (!watcher) {
00118     return NS_ERROR_FAILURE;
00119   }
00120 
00121   watcher->SetWindowCreator(sSingleton);
00122 
00123   // Set the profile which the control will use
00124   nsCOMPtr<nsIProfile> profileService(do_GetService(NS_PROFILE_CONTRACTID, &rv));
00125   if (NS_FAILED(rv))
00126     return rv;
00127 
00128   // Make a new default profile for the control if none exists.
00129   nsAutoString newProfileName(NS_LITERAL_STRING("CocoazillaControl"));
00130   PRBool profileExists = PR_FALSE;
00131   rv = profileService->ProfileExists(newProfileName.get(), &profileExists);
00132   if (NS_FAILED(rv))
00133     return rv;
00134   
00135   if (!profileExists) {
00136     rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
00137     if (NS_FAILED(rv))
00138       return rv;
00139   }
00140 
00141   rv = profileService->SetCurrentProfile(newProfileName.get());
00142   if (NS_FAILED(rv))
00143     return rv;
00144 
00145   return NS_OK;
00146 }
00147 
00148 void
00149 nsCocoaBrowserService::TermEmbedding()
00150 {
00151   if (--sNumBrowsers == 0) {
00152     NS_RELEASE(sSingleton);
00153   }
00154 }
00155 
00156 #define NS_ALERT_NIB_NAME "alert"
00157 
00158 nsAlertController* 
00159 nsCocoaBrowserService::GetAlertController()
00160 {
00161   if (!sController) {
00162     NSBundle* bundle = [NSBundle bundleForClass:[NSBrowserView class]];
00163     [bundle loadNibFile:@NS_ALERT_NIB_NAME externalNameTable:nsnull withZone:[NSApp zone]];
00164   }
00165   return sController;
00166 }
00167 
00168 void
00169 nsCocoaBrowserService::SetAlertController(nsAlertController* aController)
00170 {
00171   // XXX When should the controller be released?
00172   sController = aController;
00173   [sController retain];
00174 }
00175 
00176 // nsIFactory implementation
00177 NS_IMETHODIMP 
00178 nsCocoaBrowserService::CreateInstance(nsISupports *aOuter, 
00179                                       const nsIID & aIID, 
00180                                       void **aResult)
00181 {
00182   NS_ENSURE_ARG_POINTER(aResult);
00183 
00184   return sSingleton->QueryInterface(aIID, aResult);
00185 }
00186 
00187 NS_IMETHODIMP 
00188 nsCocoaBrowserService::LockFactory(PRBool lock)
00189 {
00190   return NS_OK;
00191 }
00192 
00193 // nsIPromptService implementation
00194 static NSWindow*
00195 GetNSWindowForDOMWindow(nsIDOMWindow* window)
00196 {
00197   nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
00198   if (!watcher) {
00199     return nsnull;
00200   }
00201   
00202   nsCOMPtr<nsIWebBrowserChrome> chrome;
00203   watcher->GetChromeForWindow(window, getter_AddRefs(chrome));
00204   if (!chrome) {
00205     return nsnull;
00206   }
00207 
00208   nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow(do_QueryInterface(chrome));
00209   if (!siteWindow) {
00210     return nsnull;
00211   }
00212 
00213   NSWindow* nswin;
00214   siteWindow->GetSiteWindow((void**)&nswin);
00215 
00216   return nswin;
00217 }
00218 
00219 // Implementation of nsIPromptService
00220 NS_IMETHODIMP 
00221 nsCocoaBrowserService::Alert(nsIDOMWindow *parent, 
00222                              const PRUnichar *dialogTitle, 
00223                              const PRUnichar *text)
00224 {
00225   nsAlertController* controller = GetAlertController();
00226   if (!controller) {
00227     return NS_ERROR_FAILURE;
00228   }
00229 
00230   NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
00231   NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
00232   NSWindow* window = GetNSWindowForDOMWindow(parent);
00233 
00234   [controller alert:window title:titleStr text:textStr];
00235 
00236   return NS_OK;
00237 }
00238 
00239 /* void alertCheck (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue); */
00240 NS_IMETHODIMP 
00241 nsCocoaBrowserService::AlertCheck(nsIDOMWindow *parent, 
00242                                   const PRUnichar *dialogTitle, 
00243                                   const PRUnichar *text, 
00244                                   const PRUnichar *checkMsg, 
00245                                   PRBool *checkValue)
00246 {
00247   nsAlertController* controller = GetAlertController();
00248   if (!controller) {
00249     return NS_ERROR_FAILURE;
00250   }
00251  
00252   NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
00253   NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
00254   NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
00255   NSWindow* window = GetNSWindowForDOMWindow(parent);
00256 
00257   if (checkValue) {
00258     BOOL valueBool = *checkValue ? YES : NO;
00259     
00260     [controller alertCheck:window title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
00261     
00262     *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
00263   }
00264   else {
00265     [controller alert:window title:titleStr text:textStr];    
00266   }
00267   
00268   return NS_OK;
00269 }
00270 
00271 /* boolean confirm (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text); */
00272 NS_IMETHODIMP 
00273 nsCocoaBrowserService::Confirm(nsIDOMWindow *parent, 
00274                                const PRUnichar *dialogTitle, 
00275                                const PRUnichar *text, 
00276                                PRBool *_retval)
00277 {
00278   nsAlertController* controller = GetAlertController();
00279   if (!controller) {
00280     return NS_ERROR_FAILURE;
00281   }
00282 
00283   NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
00284   NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
00285   NSWindow* window = GetNSWindowForDOMWindow(parent);
00286 
00287   *_retval = (PRBool)[controller confirm:window title:titleStr text:textStr];
00288   
00289   return NS_OK;
00290 }
00291 
00292 /* boolean confirmCheck (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue); */
00293 NS_IMETHODIMP 
00294 nsCocoaBrowserService::ConfirmCheck(nsIDOMWindow *parent, 
00295                                     const PRUnichar *dialogTitle, 
00296                                     const PRUnichar *text, 
00297                                     const PRUnichar *checkMsg, 
00298                                     PRBool *checkValue, PRBool *_retval)
00299 {
00300   nsAlertController* controller = GetAlertController();
00301   if (!controller) {
00302     return NS_ERROR_FAILURE;
00303   }
00304 
00305   NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
00306   NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
00307   NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
00308   NSWindow* window = GetNSWindowForDOMWindow(parent);
00309 
00310   if (checkValue) {
00311     BOOL valueBool = *checkValue ? YES : NO;
00312     
00313     *_retval = (PRBool)[controller confirmCheck:window title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
00314     
00315     *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
00316   }
00317   else {
00318     *_retval = (PRBool)[controller confirm:window title:titleStr text:textStr];
00319   }
00320   
00321   return NS_OK;
00322 }
00323 
00324 /* void confirmEx (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in unsigned long buttonFlags, in wstring button0Title, in wstring button1Title, in wstring button2Title, in wstring checkMsg, inout boolean checkValue, out PRInt32 buttonPressed); */
00325 NS_IMETHODIMP 
00326 nsCocoaBrowserService::ConfirmEx(nsIDOMWindow *parent, 
00327                                  const PRUnichar *dialogTitle, 
00328                                  const PRUnichar *text, 
00329                                  PRUint32 buttonFlags, 
00330                                  const PRUnichar *button0Title, 
00331                                  const PRUnichar *button1Title, 
00332                                  const PRUnichar *button2Title, 
00333                                  const PRUnichar *checkMsg, 
00334                                  PRBool *checkValue, PRInt32 *buttonPressed)
00335 {
00336   return NS_ERROR_NOT_IMPLEMENTED;
00337 }
00338 
00339 /* boolean prompt (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, inout wstring value, in wstring checkMsg, inout boolean checkValue); */
00340 NS_IMETHODIMP 
00341 nsCocoaBrowserService::Prompt(nsIDOMWindow *parent, 
00342                               const PRUnichar *dialogTitle, 
00343                               const PRUnichar *text, 
00344                               PRUnichar **value, 
00345                               const PRUnichar *checkMsg, 
00346                               PRBool *checkValue, 
00347                               PRBool *_retval)
00348 {
00349   nsAlertController* controller = GetAlertController();
00350   if (!controller) {
00351     return NS_ERROR_FAILURE;
00352   }
00353 
00354   NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
00355   NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
00356   NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
00357   NSMutableString* valueStr = [NSMutableString stringWithCharacters:*value length:(*value ? nsCRT::strlen(*value) : 0)];
00358     
00359   BOOL valueBool;
00360   if (checkValue) {
00361     valueBool = *checkValue ? YES : NO;
00362   }
00363   NSWindow* window = GetNSWindowForDOMWindow(parent);
00364 
00365   *_retval = (PRBool)[controller prompt:window title:titleStr text:textStr promptText:valueStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
00366 
00367   if (checkValue) {
00368     *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
00369   }
00370   PRUint32 length = [valueStr length];
00371   PRUnichar* retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
00372   [valueStr getCharacters:retStr];
00373   retStr[length] = PRUnichar(0);
00374   *value = retStr;
00375 
00376   return NS_OK;
00377 }
00378 
00379 /* boolean promptUsernameAndPassword (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, inout wstring username, inout wstring password, in wstring checkMsg, inout boolean checkValue); */
00380 NS_IMETHODIMP 
00381 nsCocoaBrowserService::PromptUsernameAndPassword(nsIDOMWindow *parent, 
00382                                                  const PRUnichar *dialogTitle, 
00383                                                  const PRUnichar *text, 
00384                                                  PRUnichar **username, 
00385                                                  PRUnichar **password, 
00386                                                  const PRUnichar *checkMsg, 
00387                                                  PRBool *checkValue, 
00388                                                  PRBool *_retval)
00389 {
00390   nsAlertController* controller = GetAlertController();
00391   if (!controller) {
00392     return NS_ERROR_FAILURE;
00393   }
00394 
00395   NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
00396   NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
00397   NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
00398   NSMutableString* userNameStr = [NSMutableString stringWithCharacters:*username length:(*username ? nsCRT::strlen(*username) : 0)];
00399   NSMutableString* passwordStr = [NSMutableString stringWithCharacters:*password length:(*password ? nsCRT::strlen(*password) : 0)];
00400     
00401   BOOL valueBool;
00402   if (checkValue) {
00403     valueBool = *checkValue ? YES : NO;
00404   }
00405   NSWindow* window = GetNSWindowForDOMWindow(parent);
00406 
00407   *_retval = (PRBool)[controller promptUserNameAndPassword:window title:titleStr text:textStr userNameText:userNameStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
00408   
00409   if (checkValue) {
00410     *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
00411   }
00412 
00413   PRUint32 length = [userNameStr length];
00414   PRUnichar* retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
00415   [userNameStr getCharacters:retStr];
00416   retStr[length] = PRUnichar(0);
00417   *username = retStr;
00418 
00419   length = [passwordStr length];
00420   retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
00421   [passwordStr getCharacters:retStr];
00422   retStr[length] = PRUnichar(0);
00423   *password = retStr;
00424 
00425   return NS_OK;
00426 }
00427 
00428 /* boolean promptPassword (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, inout wstring password, in wstring checkMsg, inout boolean checkValue); */
00429 NS_IMETHODIMP 
00430 nsCocoaBrowserService::PromptPassword(nsIDOMWindow *parent, 
00431                                       const PRUnichar *dialogTitle, 
00432                                       const PRUnichar *text, 
00433                                       PRUnichar **password, 
00434                                       const PRUnichar *checkMsg, 
00435                                       PRBool *checkValue, 
00436                                       PRBool *_retval)
00437 {
00438   nsAlertController* controller = GetAlertController();
00439   if (!controller) {
00440     return NS_ERROR_FAILURE;
00441   }
00442 
00443   NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
00444   NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
00445   NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
00446   NSMutableString* passwordStr = [NSMutableString stringWithCharacters:*password length:(*password ? nsCRT::strlen(*password) : 0)];
00447     
00448   BOOL valueBool;
00449   if (checkValue) {
00450     valueBool = *checkValue ? YES : NO;
00451   }
00452   NSWindow* window = GetNSWindowForDOMWindow(parent);
00453 
00454   *_retval = (PRBool)[controller promptPassword:window title:titleStr text:textStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
00455 
00456   if (checkValue) {
00457     *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
00458   }
00459 
00460   PRUint32 length = [passwordStr length];
00461   PRUnichar* retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
00462   [passwordStr getCharacters:retStr];
00463   retStr[length] = PRUnichar(0);
00464   *password = retStr;
00465 
00466   return NS_OK;
00467 }
00468 
00469 /* boolean select (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in PRUint32 count, [array, size_is (count)] in wstring selectList, out long outSelection); */
00470 NS_IMETHODIMP 
00471 nsCocoaBrowserService::Select(nsIDOMWindow *parent, 
00472                               const PRUnichar *dialogTitle, 
00473                               const PRUnichar *text, 
00474                               PRUint32 count, 
00475                               const PRUnichar **selectList, 
00476                               PRInt32 *outSelection, 
00477                               PRBool *_retval)
00478 {
00479   return NS_ERROR_NOT_IMPLEMENTED;
00480 }
00481 
00482 // Implementation of nsIWindowCreator
00483 /* nsIWebBrowserChrome createChromeWindow (in nsIWebBrowserChrome parent, in PRUint32 chromeFlags); */
00484 NS_IMETHODIMP 
00485 nsCocoaBrowserService::CreateChromeWindow(nsIWebBrowserChrome *parent, 
00486                                           PRUint32 chromeFlags, 
00487                                           nsIWebBrowserChrome **_retval)
00488 {
00489   return NS_ERROR_NOT_IMPLEMENTED;
00490 }
00491