Back to index

lightning-sunbird  0.9+nobinonly
XRemoteService.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* vim:expandtab:shiftwidth=4:tabstop=4:
00003  */
00004 /* ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is mozilla.org code.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Christopher Blizzard <blizzard@mozilla.org>.  Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard.  All Rights Reserved.
00021  * Portions created by the Initial Developer are Copyright (C) 2001
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "XRemoteService.h"
00041 #include "XRemoteContentListener.h"
00042 #include "nsIBrowserDOMWindow.h"
00043 
00044 #include <nsIGenericFactory.h>
00045 #include <nsIWebNavigation.h>
00046 #include <nsIDOMWindowInternal.h>
00047 #include <nsIDOMChromeWindow.h>
00048 #include <nsIDocShell.h>
00049 #include <nsIScriptGlobalObject.h>
00050 #include <nsIBaseWindow.h>
00051 #include <nsIServiceManager.h>
00052 #include <nsString.h>
00053 #include <nsCRT.h>
00054 #include <nsIPref.h>
00055 #include <nsIWindowWatcher.h>
00056 #include <nsXPCOM.h>
00057 #include <nsISupportsPrimitives.h>
00058 #include <nsIInterfaceRequestor.h>
00059 #include <nsIInterfaceRequestorUtils.h>
00060 #include <nsIDocShellTreeItem.h>
00061 #include <nsIDocShellTreeOwner.h>
00062 #include <nsIURILoader.h>
00063 #include <nsCURILoader.h>
00064 #include <nsIURIFixup.h>
00065 #include <nsCDefaultURIFixup.h>
00066 #include <nsIURI.h>
00067 #include <nsNetUtil.h>
00068 #include <nsIWindowMediator.h>
00069 #include <nsCExternalHandlerService.h>
00070 #include <nsIExternalProtocolService.h>
00071 #include <nsIProfile.h>
00072 
00073 #include "nsICmdLineHandler.h"
00074 
00075 XRemoteService::XRemoteService()
00076 {
00077 }
00078 
00079 XRemoteService::~XRemoteService()
00080 {
00081 }
00082 
00083 NS_IMPL_ISUPPORTS1(XRemoteService, nsISuiteRemoteService)
00084 
00085 NS_IMETHODIMP
00086 XRemoteService::ParseCommand(const char *aCommand, nsIDOMWindow* aWindow)
00087 {
00088   NS_ASSERTION(aCommand, "Tell me what to do, or shut up!");
00089 
00090   // begin our parse
00091   nsCString tempString(aCommand);
00092 
00093   // find the () in the command
00094   PRInt32 begin_arg = tempString.FindChar('(');
00095   PRInt32 end_arg = tempString.RFindChar(')');
00096 
00097   // make sure that both were found, the string doesn't start with '('
00098   // and that the ')' follows the '('
00099   if (begin_arg == kNotFound || end_arg == kNotFound ||
00100       begin_arg == 0 || end_arg < begin_arg)
00101     return NS_ERROR_INVALID_ARG;
00102 
00103   // truncate the closing paren and anything following it
00104   tempString.Truncate(end_arg);
00105 
00106   // save the argument and trim whitespace off of it
00107   nsCString argument(tempString);
00108   argument.Cut(0, begin_arg + 1);
00109   argument.Trim(" ", PR_TRUE, PR_TRUE);
00110 
00111   // remove the argument
00112   tempString.Truncate(begin_arg);
00113 
00114   // get the action, strip off whitespace and convert to lower case
00115   nsCString action(tempString);
00116   action.Trim(" ", PR_TRUE, PR_TRUE);
00117   ToLowerCase(action);
00118 
00119   // pull off the noraise argument if it's there.
00120   PRUint32  index = 0;
00121   PRBool    raiseWindow = PR_TRUE;
00122   nsCString lastArgument;
00123 
00124   FindLastInList(argument, lastArgument, &index);
00125   if (lastArgument.LowerCaseEqualsLiteral("noraise")) {
00126     argument.Truncate(index);
00127     raiseWindow = PR_FALSE;
00128   }
00129 
00130   nsresult rv = NS_OK;
00131   
00132   /*   
00133       openURL ( ) 
00134             Prompts for a URL with a dialog box. 
00135       openURL (URL) 
00136             Opens the specified document without prompting. 
00137       openURL (URL, new-window) 
00138             Create a new window displaying the the specified document. 
00139   */
00140 
00141   /*
00142       openFile ( ) 
00143             Prompts for a file with a dialog box. 
00144       openFile (File) 
00145             Opens the specified file without prompting. 
00146 
00147   */
00148 
00149   if (action.Equals("openurl") || action.Equals("openfile")) {
00150     rv = OpenURL(argument, aWindow, PR_TRUE);
00151   }
00152 
00153   /*
00154       saveAs ( ) 
00155             Prompts for a file with a dialog box (like the menu item). 
00156       saveAs (Output-File) 
00157             Writes HTML to the specified file without prompting. 
00158       saveAs (Output-File, Type) 
00159             Writes to the specified file with the type specified -
00160            the type may be HTML, Text, or PostScript. 
00161 
00162   */
00163 
00164   else if (action.Equals("saveas")) {
00165     if (argument.IsEmpty()) {
00166       rv = NS_ERROR_NOT_IMPLEMENTED;
00167     }
00168     else {
00169       // check to see if it has a type on it
00170       index = 0;
00171       FindLastInList(argument, lastArgument, &index);
00172       if (lastArgument.LowerCaseEqualsLiteral("html")) {
00173        argument.Truncate(index);
00174        rv = NS_ERROR_NOT_IMPLEMENTED;
00175       }
00176       else if (lastArgument.EqualsIgnoreCase("text", PR_TRUE)) {
00177        argument.Truncate(index);
00178        rv = NS_ERROR_NOT_IMPLEMENTED;
00179       }
00180       else if (lastArgument.EqualsIgnoreCase("postscript", PR_TRUE)) {
00181        argument.Truncate(index);
00182        rv = NS_ERROR_NOT_IMPLEMENTED;
00183       }
00184       else {
00185        rv = NS_ERROR_NOT_IMPLEMENTED;
00186       }
00187     }
00188    
00189   }
00190 
00191   /*
00192       mailto ( ) 
00193             pops up the mail dialog with the To: field empty. 
00194       mailto (a, b, c) 
00195             Puts the addresses "a, b, c" in the default To: field. 
00196 
00197   */
00198 
00199   else if (action.Equals("mailto")) {
00200     // if you prepend mailto: to the string it will be a mailto: url
00201     // and openurl should work fine.
00202     nsCString tempArg("mailto:");
00203     tempArg.Append(argument);
00204     rv = OpenURL(tempArg, aWindow, PR_FALSE);
00205   }
00206 
00207   /*
00208       addBookmark ( ) 
00209             Adds the current document to the bookmark list. 
00210       addBookmark (URL) 
00211             Adds the given document to the bookmark list. 
00212       addBookmark (URL, Title) 
00213             Adds the given document to the bookmark list,
00214            with the given title. 
00215   */
00216 
00217   else if (action.Equals("addbookmark")) {
00218     rv = NS_ERROR_NOT_IMPLEMENTED;
00219   }
00220 
00221   /* some extensions! */
00222   
00223   /*
00224       ping()
00225          Just responds with an OK to let a client know that we are here.
00226   */
00227 
00228   else if (action.Equals("ping")) {
00229     // the 200 will get filled in below
00230     rv = NS_OK;
00231   }
00232 
00233   /*
00234       xfeDoCommand()
00235        This is an interface to make the xfe "do stuff."  Lifted from
00236        the old Netscape 4.x interface.
00237   */
00238 
00239   else if (action.Equals("xfedocommand")) {
00240     rv = XfeDoCommand(argument, aWindow);
00241   }
00242 
00243   // bad command
00244   else {
00245     rv = NS_ERROR_FAILURE;
00246   }
00247 
00248   return rv;
00249 }
00250 
00251 void
00252 XRemoteService::FindRestInList(nsCString &aString, nsCString &retString,
00253                                PRUint32 *aIndexRet)
00254 {
00255   // init our return
00256   *aIndexRet = 0;
00257   nsCString tempString;
00258   PRInt32   strIndex;
00259   // find out if there's a comma from the start of the string
00260   strIndex = aString.FindChar(',');
00261 
00262   // give up now if you can
00263   if (strIndex == kNotFound)
00264     return;
00265 
00266   // cut the string down to the first ,
00267   tempString = Substring(aString, strIndex+1, aString.Length());
00268 
00269   // strip off leading + trailing whitespace
00270   tempString.Trim(" ", PR_TRUE, PR_TRUE);
00271 
00272   // see if we've reduced it to nothing
00273   if (tempString.IsEmpty())
00274     return;
00275 
00276   *aIndexRet = strIndex;
00277 
00278   // otherwise, return it as a new C string
00279   retString = tempString;
00280 
00281 }
00282 
00283 void
00284 XRemoteService::FindLastInList(nsCString &aString, nsCString &retString,
00285                             PRUint32 *aIndexRet)
00286 {
00287   // init our return
00288   *aIndexRet = 0;
00289   // make a copy to work with
00290   nsCString tempString = aString;
00291   PRInt32   strIndex;
00292   // find out of there's a , at the end of the string
00293   strIndex = tempString.RFindChar(',');
00294 
00295   // give up now if you can
00296   if (strIndex == kNotFound)
00297     return;
00298 
00299   // cut the string down to the first ,
00300   tempString.Cut(0, strIndex + 1);
00301 
00302   // strip off leading + trailing whitespace
00303   tempString.Trim(" ", PR_TRUE, PR_TRUE);
00304 
00305   // see if we've reduced it to nothing
00306   if (tempString.IsEmpty())
00307     return;
00308 
00309   *aIndexRet = strIndex;
00310 
00311   // otherwise, return it as a new C string
00312   retString = tempString;
00313 
00314 }
00315 
00316 nsresult
00317 XRemoteService::OpenChromeWindow(nsIDOMWindow *aParent,
00318                              const char *aUrl, const char *aFeatures,
00319                              nsISupports *aArguments,
00320                              nsIDOMWindow **_retval)
00321 {
00322   nsCOMPtr<nsIWindowWatcher> watcher;
00323   watcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
00324     
00325   if (!watcher)
00326     return NS_ERROR_FAILURE;
00327 
00328   return watcher->OpenWindow(aParent, aUrl, "_blank",
00329                           aFeatures, aArguments, _retval);
00330 }
00331 
00332 nsresult
00333 XRemoteService::GetBrowserLocation(char **_retval)
00334 {
00335   // get the browser chrome URL
00336   nsCOMPtr<nsIPref> prefs;
00337   prefs = do_GetService(NS_PREF_CONTRACTID);
00338   if (!prefs)
00339     return NS_ERROR_FAILURE;
00340   
00341   prefs->CopyCharPref("browser.chromeURL", _retval);
00342 
00343   // fallback
00344   if (!*_retval)
00345     *_retval = nsCRT::strdup("chrome://navigator/content/navigator.xul");
00346 
00347   return NS_OK;
00348 }
00349 
00350 nsresult
00351 XRemoteService::GetMailLocation(char **_retval)
00352 {
00353   // get the mail chrome URL
00354   nsCOMPtr<nsIPref> prefs;
00355   prefs = do_GetService(NS_PREF_CONTRACTID);
00356   if (!prefs)
00357     return NS_ERROR_FAILURE;
00358   
00359   PRInt32 retval = 0;
00360   nsresult rv;
00361   rv = prefs->GetIntPref("mail.pane_config", &retval);
00362   if (NS_FAILED(rv))
00363     return NS_ERROR_FAILURE;
00364 
00365   if (!retval)
00366     *_retval = nsCRT::strdup("chrome://messenger/content/messenger.xul");
00367   else
00368     *_retval = nsCRT::strdup("chrome://messenger/content/mail3PaneWindowVertLayout.xul");
00369 
00370   return NS_OK;
00371   
00372 }
00373 
00374 nsresult
00375 XRemoteService::GetComposeLocation(const char **_retval)
00376 {
00377   // get the Compose chrome URL
00378   *_retval = "chrome://messenger/content/messengercompose/messengercompose.xul";
00379 
00380   return NS_OK;
00381 }
00382 
00383 nsresult
00384 XRemoteService::GetCalendarLocation(char **_retval)
00385 {
00386   // get the calendar chrome URL
00387   nsCOMPtr<nsIPref> prefs;
00388   prefs = do_GetService(NS_PREF_CONTRACTID);
00389   if (!prefs)
00390     return NS_ERROR_FAILURE;
00391 
00392   prefs->CopyCharPref("calendar.chromeURL", _retval);
00393 
00394   // fallback
00395   if (!*_retval)
00396     *_retval = nsCRT::strdup("chrome://calendar/content/calendar.xul");
00397 
00398   return NS_OK;
00399 }
00400 
00401 PRBool
00402 XRemoteService::MayOpenURL(const nsCString &aURL)
00403 {
00404   // by default, we assume nothing can be loaded.
00405   PRBool allowURL= PR_FALSE;
00406 
00407   nsCOMPtr<nsIExternalProtocolService> extProtService =
00408       do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
00409   if (extProtService) {
00410     nsCAutoString scheme;
00411 
00412     // empty URLs will be treated as about:blank by OpenURL
00413     if (aURL.IsEmpty()) {
00414       scheme.AssignLiteral("about");
00415     }
00416     else {
00417       nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID);
00418       if (fixup) {
00419         nsCOMPtr<nsIURI> uri;
00420         nsresult rv =
00421           fixup->CreateFixupURI(aURL, nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
00422                                 getter_AddRefs(uri));
00423         if (NS_SUCCEEDED(rv) && uri) {
00424           uri->GetScheme(scheme);
00425         }
00426       }
00427     }
00428 
00429     if (!scheme.IsEmpty()) {
00430       // if the given URL scheme corresponds to an exposed protocol, then we
00431       // can try to load it.  otherwise, we must not.
00432       PRBool isExposed;
00433       nsresult rv = extProtService->IsExposedProtocol(scheme.get(), &isExposed);
00434       if (NS_SUCCEEDED(rv) && isExposed)
00435         allowURL = PR_TRUE; // ok, we can load this URL.
00436     }
00437   }
00438 
00439   return allowURL;
00440 }
00441 
00442 nsresult
00443 XRemoteService::OpenURL(nsCString &aArgument,
00444                      nsIDOMWindow *aParent,
00445                      PRBool aOpenBrowser)
00446 {
00447   // the eventual toplevel target of the load
00448   nsCOMPtr<nsIDOMWindowInternal> finalWindow = do_QueryInterface(aParent);
00449 
00450   // see if there's a new-window or new-tab argument on the end
00451   nsCString lastArgument;
00452   PRBool    newWindow = PR_FALSE, newTab = PR_FALSE;
00453   PRUint32  index = 0;
00454   FindLastInList(aArgument, lastArgument, &index);
00455 
00456   newTab = lastArgument.LowerCaseEqualsLiteral("new-tab");
00457 
00458   if (newTab || lastArgument.LowerCaseEqualsLiteral("new-window")) {
00459     aArgument.Truncate(index);
00460     // only open new windows if it's OK to do so
00461     if (!newTab && aOpenBrowser)
00462       newWindow = PR_TRUE;
00463     // recheck for a possible noraise argument since it might have
00464     // been before the new-window argument
00465     FindLastInList(aArgument, lastArgument, &index);
00466     if (lastArgument.LowerCaseEqualsLiteral("noraise"))
00467       aArgument.Truncate(index);
00468   }
00469 
00470   nsCOMPtr<nsIBrowserDOMWindow> bwin;
00471 
00472   // If it's OK to open a new browser window and a new window flag
00473   // wasn't passed in then try to find a current window.  If that's
00474   // not found then go ahead and open a new window.
00475   // If we're trying to open a new tab, we'll fall back to opening
00476   // a new window if there's no browser window open, so look for it
00477   // here.
00478   if (aOpenBrowser && (!newWindow || newTab)) {
00479     nsCOMPtr<nsIDOMWindowInternal> lastUsedWindow;
00480     FindWindow(NS_LITERAL_STRING("navigator:browser").get(),
00481               getter_AddRefs(lastUsedWindow));
00482 
00483     if (lastUsedWindow) {
00484       finalWindow = lastUsedWindow;
00485       nsCOMPtr<nsIWebNavigation> navNav(do_GetInterface(finalWindow));
00486       nsCOMPtr<nsIDocShellTreeItem> navItem(do_QueryInterface(navNav));
00487       if (navItem) {
00488         nsCOMPtr<nsIDocShellTreeItem> rootItem;
00489         navItem->GetRootTreeItem(getter_AddRefs(rootItem));
00490         nsCOMPtr<nsIDOMWindow> rootWin(do_GetInterface(rootItem));
00491         nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(rootWin));
00492         if (chromeWin)
00493           chromeWin->GetBrowserDOMWindow(getter_AddRefs(bwin));
00494       }
00495     }
00496     if (!finalWindow || !bwin)
00497       newWindow = PR_TRUE;
00498   }
00499 
00500   // check if we can handle this type of URL
00501   if (!MayOpenURL(aArgument))
00502     return NS_ERROR_ABORT;
00503 
00504   nsresult rv = NS_OK;
00505 
00506   // try to fixup the argument passed in
00507   nsString url;
00508   url.AssignWithConversion(aArgument.get());
00509 
00510   nsCOMPtr<nsIURI> uri;
00511   NS_NewURI(getter_AddRefs(uri), url);
00512 
00513   if (newWindow) {
00514     nsXPIDLCString urlString;
00515     GetBrowserLocation(getter_Copies(urlString));
00516     if (!urlString)
00517       return NS_ERROR_FAILURE;
00518 
00519     nsCOMPtr<nsISupportsString> arg;
00520     arg = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
00521     if (!arg)
00522       return NS_ERROR_FAILURE;
00523     
00524     // save the url into the string object
00525     arg->SetData(url);
00526     
00527     nsCOMPtr<nsIDOMWindow> window;
00528     rv = OpenChromeWindow(finalWindow, urlString, "chrome,all,dialog=no",
00529                        arg, getter_AddRefs(window));
00530   }
00531 
00532   // if no new window flag was set but there's no parent then we have
00533   // to pass everything off to the uri loader
00534   else if (!finalWindow) {
00535     nsCOMPtr<nsIURILoader> loader;
00536     loader = do_GetService(NS_URI_LOADER_CONTRACTID);
00537     if (!loader)
00538       return NS_ERROR_FAILURE;
00539     
00540     XRemoteContentListener *listener;
00541     listener = new XRemoteContentListener();
00542     if (!listener)
00543       return NS_ERROR_FAILURE;
00544 
00545     // we own it
00546     NS_ADDREF(listener);
00547     nsCOMPtr<nsISupports> listenerRef;
00548     listenerRef = do_QueryInterface(NS_STATIC_CAST(nsIURIContentListener *,
00549                                              listener));
00550     // now the listenerref is the only reference
00551     NS_RELEASE(listener);
00552 
00553     // double-check our uri object
00554     if (!uri)
00555       return NS_ERROR_FAILURE;
00556 
00557     // open a channel
00558     nsCOMPtr<nsIChannel> channel;
00559     rv = NS_NewChannel(getter_AddRefs(channel), uri);
00560     if (NS_FAILED(rv))
00561       return NS_ERROR_FAILURE;
00562 
00563     // load it
00564     rv = loader->OpenURI(channel, PR_TRUE, listener);
00565   }
00566 
00567   else if (newTab && aOpenBrowser) {
00568     if (bwin && uri) {
00569       nsCOMPtr<nsIDOMWindow> container;
00570       rv = bwin->OpenURI(uri, 0,
00571                          nsIBrowserDOMWindow::OPEN_NEWTAB,
00572                          nsIBrowserDOMWindow::OPEN_EXTERNAL,
00573                          getter_AddRefs(container));
00574     }
00575     else {
00576       NS_ERROR("failed to open remote URL in new tab");
00577       return NS_ERROR_FAILURE;
00578     }
00579   }
00580 
00581   else if (bwin && uri) { // unspecified new browser URL; use prefs
00582     nsCOMPtr<nsIDOMWindow> container;
00583     rv = bwin->OpenURI(uri, 0,
00584                        nsIBrowserDOMWindow::OPEN_DEFAULTWINDOW,
00585                        nsIBrowserDOMWindow::OPEN_EXTERNAL,
00586                        getter_AddRefs(container));
00587     if (NS_SUCCEEDED(rv))
00588       return NS_OK;
00589   }
00590 
00591   else { // non-browser URLs
00592     // find the primary content shell for the window that we've been
00593     // asked to load into.
00594     nsCOMPtr<nsIScriptGlobalObject> scriptObject;
00595     scriptObject = do_QueryInterface(finalWindow);
00596     if (!scriptObject) {
00597       NS_WARNING("Failed to get script object for browser instance");
00598       return NS_ERROR_FAILURE;
00599     }
00600 
00601     nsCOMPtr<nsIDocShell> docShell = scriptObject->GetDocShell();
00602     if (!docShell) {
00603       NS_WARNING("Failed to get docshell object for browser instance");
00604       return NS_ERROR_FAILURE;
00605     }
00606 
00607     nsCOMPtr<nsIDocShellTreeItem> item(do_QueryInterface(docShell));
00608     if (!item) {
00609       NS_WARNING("failed to get doc shell tree item for browser instance");
00610       return NS_ERROR_FAILURE;
00611     }
00612 
00613     nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
00614     item->GetTreeOwner(getter_AddRefs(treeOwner));
00615     if (!treeOwner) {
00616       NS_WARNING("failed to get tree owner");
00617       return NS_ERROR_FAILURE;
00618     }
00619 
00620     nsCOMPtr<nsIDocShellTreeItem> primaryContent;
00621     treeOwner->GetPrimaryContentShell(getter_AddRefs(primaryContent));
00622 
00623     docShell = do_QueryInterface(primaryContent);
00624     if (!docShell) {
00625       NS_WARNING("failed to get docshell from primary content item");
00626       return NS_ERROR_FAILURE;
00627     }
00628 
00629     nsCOMPtr<nsIWebNavigation> webNav;
00630     webNav = do_GetInterface(docShell);
00631     if (!webNav) {
00632       NS_WARNING("failed to get web nav from inner docshell");
00633       return NS_ERROR_FAILURE;
00634     }
00635 
00636     rv = webNav->LoadURI(url.get(),
00637                          nsIWebNavigation::LOAD_FLAGS_NONE,
00638                          nsnull,
00639                          nsnull,
00640                          nsnull);
00641 
00642   }
00643 
00644   return rv;
00645 }
00646 
00647 nsresult
00648 XRemoteService::XfeDoCommand(nsCString &aArgument,
00649                              nsIDOMWindow *aParent)
00650 {
00651   nsresult rv = NS_OK;
00652   
00653   // see if there are any arguments on the end
00654   nsCString restArgument;
00655   PRUint32  index;
00656   FindRestInList(aArgument, restArgument, &index);
00657 
00658   if (!restArgument.IsEmpty())
00659     aArgument.Truncate(index);
00660   nsCOMPtr<nsISupportsString> arg;
00661   arg = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
00662   
00663   if (NS_FAILED(rv))
00664     return rv;
00665   
00666   // pass the second argument as parameter
00667   arg->SetData(NS_ConvertUTF8toUCS2(restArgument));
00668 
00669   // someone requested opening mail/news
00670   if (aArgument.LowerCaseEqualsLiteral("openinbox")) {
00671 
00672     // check to see if it's already running
00673     nsCOMPtr<nsIDOMWindowInternal> domWindow;
00674 
00675     rv = FindWindow(NS_LITERAL_STRING("mail:3pane").get(),
00676                     getter_AddRefs(domWindow));
00677 
00678     if (NS_FAILED(rv))
00679       return rv;
00680 
00681     // focus the window if it was found
00682     if (domWindow) {
00683       domWindow->Focus();
00684     }
00685 
00686     // otherwise open a new mail/news window
00687     else {
00688       // get the mail chrome location
00689       nsXPIDLCString mailLocation;
00690       GetMailLocation(getter_Copies(mailLocation));
00691       if (!mailLocation)
00692        return NS_ERROR_FAILURE;
00693 
00694       nsCOMPtr<nsIDOMWindow> newWindow;
00695       rv = OpenChromeWindow(0, mailLocation, "chrome,all,dialog=no",
00696                             arg, getter_AddRefs(newWindow));
00697     }
00698   }
00699 
00700   // open a new browser window
00701   else if (aArgument.LowerCaseEqualsLiteral("openbrowser")) {
00702     // Get the browser URL and the default start page URL.
00703     nsCOMPtr<nsICmdLineHandler> browserHandler =
00704         do_GetService("@mozilla.org/commandlinehandler/general-startup;1?type=browser");
00705 
00706     if (!browserHandler)
00707         return NS_ERROR_FAILURE;
00708 
00709     nsXPIDLCString browserLocation;
00710     browserHandler->GetChromeUrlForTask(getter_Copies(browserLocation));
00711 
00712     nsXPIDLString startPage;
00713     browserHandler->GetDefaultArgs(getter_Copies(startPage));
00714 
00715     arg->SetData(startPage);
00716 
00717     nsCOMPtr<nsIDOMWindow> newWindow;
00718     rv = OpenChromeWindow(0, browserLocation, "chrome,all,dialog=no",
00719                           arg, getter_AddRefs(newWindow));
00720   }
00721 
00722   // open a new compose window
00723   else if (aArgument.LowerCaseEqualsLiteral("composemessage")) {
00724     /*
00725      *  Here we change to OpenChromeWindow instead of OpenURL so as to
00726      *  pass argument values to the compose window, especially attachments
00727      */
00728     const char * composeLocation;
00729     rv = GetComposeLocation(&composeLocation);
00730     if (rv != NS_OK)
00731       return NS_ERROR_FAILURE;
00732 
00733     nsCOMPtr<nsIDOMWindow> newWindow;
00734     rv = OpenChromeWindow(0, composeLocation, "chrome,all,dialog=no",
00735                           arg, getter_AddRefs(newWindow));
00736   }
00737 
00738   // open a new calendar window
00739   else if (aArgument.LowerCaseEqualsLiteral("opencalendar")) {
00740 
00741     // check to see if it's already running
00742     nsCOMPtr<nsIDOMWindowInternal> aWindow;
00743 
00744     rv = FindWindow(NS_LITERAL_STRING("calendarMainWindow").get(),
00745                   getter_AddRefs(aWindow));
00746 
00747     if (NS_FAILED(rv))
00748       return rv;
00749 
00750     // focus the window if it was found
00751     if (aWindow) {
00752       aWindow->Focus();
00753     }
00754 
00755     // otherwise open a new calendar window
00756     else {
00757       nsXPIDLCString calendarChrome;
00758       rv = GetCalendarLocation(getter_Copies(calendarChrome));
00759       if (NS_FAILED(rv))
00760         return rv;
00761 
00762       nsCOMPtr<nsIDOMWindow> newWindow;
00763       rv = OpenChromeWindow(0, calendarChrome, "chrome,all,dialog=no",
00764                             arg, getter_AddRefs(newWindow));
00765     }
00766   }
00767 
00768   return rv;
00769 }
00770 
00771 nsresult
00772 XRemoteService::FindWindow(const PRUnichar *aType,
00773                         nsIDOMWindowInternal **_retval)
00774 {
00775   nsCOMPtr<nsIWindowMediator> mediator;
00776   mediator = do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
00777 
00778   if (!mediator)
00779     return NS_ERROR_FAILURE;
00780 
00781   return mediator->GetMostRecentWindow(aType, _retval);
00782 }
00783 
00784 NS_GENERIC_FACTORY_CONSTRUCTOR(XRemoteService)
00785 
00786 static const nsModuleComponentInfo components[] = {
00787   { "XRemoteService",
00788     NS_XREMOTESERVICE_CID,
00789     "@mozilla.org/browser/xremoteservice;2",
00790     XRemoteServiceConstructor }
00791 };
00792 
00793 NS_IMPL_NSGETMODULE(XRemoteServiceModule, components)