Back to index

lightning-sunbird  0.9+nobinonly
nsMessengerBootstrap.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; 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  *   Alec Flett <alecf@netscape.com>
00024  *   Scott Putterman <putterman@netscape.com>
00025  *   Seth Spitzer <sspitzer@netscape.com>
00026  *   Pierre Phaneuf <pp@ludusdesign.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either of the GNU General Public License Version 2 or later (the "GPL"),
00030  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #include "nsMessengerBootstrap.h"
00043 #include "nsCOMPtr.h"
00044 
00045 #include "nsDOMCID.h"
00046 #include "nsMsgBaseCID.h"
00047 #include "nsIMsgMailSession.h"
00048 #include "nsIMsgFolderCache.h"
00049 #include "nsIPrefService.h"
00050 #include "nsIPrefBranch.h"
00051 #include "nsIDOMWindow.h"
00052 #include "nsXPCOM.h"
00053 #include "nsISupportsPrimitives.h"
00054 #include "nsIWindowWatcher.h"
00055 #include "nsString.h"
00056 #include "nsIURI.h"
00057 #include "nsIDialogParamBlock.h"
00058 #include "nsUnicharUtils.h"
00059 #include "nsMsgUtils.h"
00060 
00061 #ifdef MOZ_XUL_APP
00062 #include "nsICommandLine.h"
00063 #include "nsILocalFile.h"
00064 #include "nsNetUtil.h"
00065 #include "nsIFileURL.h"
00066 #include "nsNativeCharsetUtils.h"
00067 #include "nsIRDFResource.h"
00068 #include "nsIRDFService.h"
00069 #include "nsIMsgHdr.h"
00070 #include "nsEscape.h"
00071 #endif // MOZ_XUL_APP
00072 
00073 NS_IMPL_THREADSAFE_ADDREF(nsMessengerBootstrap)
00074 NS_IMPL_THREADSAFE_RELEASE(nsMessengerBootstrap)
00075 
00076 NS_IMPL_QUERY_INTERFACE2(nsMessengerBootstrap,
00077                          ICOMMANDLINEHANDLER,
00078                          nsIMessengerWindowService)
00079 
00080 nsMessengerBootstrap::nsMessengerBootstrap()
00081 {
00082 }
00083 
00084 nsMessengerBootstrap::~nsMessengerBootstrap()
00085 {
00086 }
00087 
00088 #ifdef MOZ_XUL_APP
00089 NS_IMETHODIMP
00090 nsMessengerBootstrap::Handle(nsICommandLine* aCmdLine)
00091 {
00092   nsresult rv;
00093   PRBool found;
00094 
00095   nsCOMPtr<nsIWindowWatcher> wwatch (do_GetService(NS_WINDOWWATCHER_CONTRACTID));
00096   NS_ENSURE_TRUE(wwatch, NS_ERROR_FAILURE);
00097 
00098   nsCOMPtr<nsIDOMWindow> opened;
00099 
00100   rv = aCmdLine->HandleFlag(NS_LITERAL_STRING("options"), PR_FALSE, &found);
00101   if (NS_SUCCEEDED(rv) && found) {
00102     wwatch->OpenWindow(nsnull, "chrome://messenger/content/preferences/preferences.xul", "_blank",
00103                       "chrome,dialog=no,all", nsnull, getter_AddRefs(opened));
00104     aCmdLine->SetPreventDefault(PR_TRUE);
00105   }
00106   
00107   nsAutoString mailUrl; // -mail or -mail <some url> 
00108   rv = aCmdLine->HandleFlagWithParam(NS_LITERAL_STRING("mail"), PR_FALSE, mailUrl);
00109   if (NS_SUCCEEDED(rv) && !mailUrl.IsEmpty()) 
00110   {
00111     nsCOMPtr<nsISupportsArray> argsArray = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
00112     NS_ENSURE_SUCCESS(rv, rv);
00113 
00114     // create scriptable versions of our strings that we can store in our nsISupportsArray....
00115     if (!mailUrl.IsEmpty())
00116     {
00117       nsCOMPtr<nsISupportsString> scriptableURL (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
00118       NS_ENSURE_TRUE(scriptableURL, NS_ERROR_FAILURE);
00119   
00120       scriptableURL->SetData((mailUrl));
00121       argsArray->AppendElement(scriptableURL);
00122     }
00123 
00124     wwatch->OpenWindow(nsnull, "chrome://messenger/content/", "_blank",
00125                        "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar,dialog=no", argsArray, getter_AddRefs(opened));
00126     aCmdLine->SetPreventDefault(PR_TRUE);
00127     return NS_OK;
00128   } 
00129 
00130   PRInt32 numArgs;
00131   aCmdLine->GetLength(&numArgs);
00132   if (numArgs > 0)
00133   {
00134     nsAutoString arg;
00135     aCmdLine->GetArgument(0, arg);
00136 #ifdef XP_MACOSX
00137     if (StringEndsWith(arg, NS_LITERAL_STRING(".mozeml"), nsCaseInsensitiveStringComparator()))
00138     {
00139       // parse file name - get path to containing folder, and message-id of message we're looking for
00140       // Then, open that message (in a 3-pane window?)
00141       // We're going to have a native path file url:
00142       // file://<folder path>.mozmsgs/<message-id>.mozeml
00143       PRInt32 mozmsgsIndex = arg.Find(NS_LITERAL_STRING(".mozmsgs"));
00144       // take off the file:// part
00145       nsString folderPath;
00146       arg.Left(folderPath, mozmsgsIndex);
00147       // need to convert to 8 bit chars...i.e., a local path.
00148       nsCAutoString nativeArg;
00149       NS_CopyUnicodeToNative(folderPath, nativeArg);
00150       nsCString folderUri;
00151       rv = MsgMailboxGetURI(nativeArg.get(), folderUri);
00152       NS_ENSURE_SUCCESS(rv, rv);
00153       nsCOMPtr<nsIRDFService> rdf(do_GetService("@mozilla.org/rdf/rdf-service;1", &rv));
00154       NS_ENSURE_SUCCESS(rv, rv);
00155       nsCOMPtr<nsIRDFResource> res;
00156       rv = rdf->GetResource(folderUri, getter_AddRefs(res));
00157       NS_ENSURE_SUCCESS(rv, rv);
00158       nsCOMPtr<nsIMsgFolder> containingFolder;
00159       containingFolder = do_QueryInterface(res, &rv);
00160       NS_ENSURE_SUCCESS(rv, rv);
00161       // now we play a little game to deal with IMAP case-insensitivity of the INBOX.
00162       nsCOMPtr <nsIMsgIncomingServer> server;
00163       rv = containingFolder->GetServer(getter_AddRefs(server));
00164       NS_ENSURE_SUCCESS(rv, rv);
00165       rv = server->GetMsgFolderFromURI(containingFolder, folderUri.get(), getter_AddRefs(containingFolder));
00166       NS_ENSURE_TRUE(containingFolder, NS_ERROR_FAILURE);
00167       // once we have the folder uri, open the db and search for the message id.
00168       nsAutoString unicodeMessageid;
00169       // strip off .mozeml at the end as well
00170       arg.Mid(unicodeMessageid, mozmsgsIndex + 9, arg.Length() - (mozmsgsIndex + 9 + 7));
00171       nsCAutoString messageId;
00172       NS_CopyUnicodeToNative(unicodeMessageid, messageId);
00173       nsCOMPtr <nsIMsgDatabase> msgDB;
00174       containingFolder->GetMsgDatabase(nsnull, getter_AddRefs(msgDB));
00175       NS_UnescapeURL(messageId);
00176       nsCOMPtr<nsIMsgDBHdr> msgHdr;
00177       if (msgDB)
00178         msgDB->GetMsgHdrForMessageID(messageId.get(), getter_AddRefs(msgHdr));
00179       if (msgHdr)
00180       {
00181         nsMsgKey msgKey;
00182         msgHdr->GetMessageKey(&msgKey);
00183         rv = OpenMessengerWindowWithUri("mail:messageWindow", folderUri.get(), msgKey);  
00184         return rv;
00185       }
00186     }
00187 #endif
00188     if (StringEndsWith(arg, NS_LITERAL_STRING(".eml"), nsCaseInsensitiveStringComparator()))
00189     {
00190       nsCOMPtr<nsILocalFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
00191       NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
00192       rv = file->InitWithPath(arg);
00193       NS_ENSURE_SUCCESS(rv, rv);
00194       // should we check that the file exists, or looks like a mail message?
00195 
00196       nsCOMPtr<nsIURI> uri;
00197       NS_NewFileURI(getter_AddRefs(uri), file);
00198       nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(uri));
00199       NS_ENSURE_TRUE(fileURL, NS_ERROR_FAILURE);
00200 
00201       // create scriptable versions of our strings that we can store in our nsISupportsArray....
00202       nsCOMPtr<nsISupportsString> scriptableURL (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
00203       NS_ENSURE_TRUE(scriptableURL, NS_ERROR_FAILURE);
00204 
00205       fileURL->SetQuery(NS_LITERAL_CSTRING("?type=application/x-message-display"));
00206 
00207       wwatch->OpenWindow(nsnull, "chrome://messenger/content/messageWindow.xul", "_blank",
00208                          "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar,dialog=no", fileURL, getter_AddRefs(opened));
00209       aCmdLine->SetPreventDefault(PR_TRUE);
00210     }
00211     return NS_OK;
00212 
00213   }
00214   return NS_OK;
00215 }
00216 
00217 NS_IMETHODIMP
00218 nsMessengerBootstrap::GetHelpInfo(nsACString& aResult)
00219 {
00220   aResult.Assign(NS_LITERAL_CSTRING(
00221     "  -mail                Open the mail folder view.\n"
00222     "  -options             Open the options dialog.\n"));
00223 
00224   return NS_OK;
00225 }
00226 
00227 #else
00228 CMDLINEHANDLER3_IMPL(nsMessengerBootstrap,"-mail","general.startup.mail","Start with mail.",NS_MAILSTARTUPHANDLER_CONTRACTID,"Mail Cmd Line Handler",PR_TRUE,"", PR_TRUE)
00229 
00230 NS_IMETHODIMP nsMessengerBootstrap::GetChromeUrlForTask(char **aChromeUrlForTask) 
00231 { 
00232   if (!aChromeUrlForTask) return NS_ERROR_FAILURE; 
00233   nsCOMPtr<nsIPrefBranch> pPrefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
00234   if (pPrefBranch)
00235   {
00236     nsresult rv;
00237     PRInt32 layout;
00238     rv = pPrefBranch->GetIntPref("mail.pane_config", &layout);        
00239     if(NS_SUCCEEDED(rv))
00240     {
00241       if(layout == 0)
00242         *aChromeUrlForTask = PL_strdup("chrome://messenger/content/messenger.xul");
00243       else
00244         *aChromeUrlForTask = PL_strdup("chrome://messenger/content/mail3PaneWindowVertLayout.xul");
00245       
00246       return NS_OK;
00247       
00248     }  
00249   }
00250   *aChromeUrlForTask = PL_strdup("chrome://messenger/content/messenger.xul"); 
00251 
00252   return NS_OK; 
00253 }
00254 #endif
00255 
00256 NS_IMETHODIMP nsMessengerBootstrap::OpenMessengerWindowWithUri(const char *windowType, const char * aFolderURI, nsMsgKey aMessageKey)
00257 {
00258   nsresult rv;
00259   PRBool standAloneMsgWindow = PR_FALSE;
00260 #ifdef MOZ_XUL_APP
00261   nsCAutoString chromeurl("chrome://messenger/content/");
00262   if (windowType && !strcmp(windowType, "mail:messageWindow"))
00263   {
00264     chromeurl.Append("messageWindow.xul");
00265     standAloneMsgWindow = PR_TRUE;    
00266   }
00267 #else
00268   nsXPIDLCString chromeurl;
00269   rv = GetChromeUrlForTask(getter_Copies(chromeurl));
00270   if (NS_FAILED(rv)) return rv;
00271 #endif
00272 
00273   nsCOMPtr<nsISupportsArray> argsArray;
00274   rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
00275   NS_ENSURE_SUCCESS(rv, rv);
00276 
00277   // create scriptable versions of our strings that we can store in our nsISupportsArray....
00278   if (aFolderURI)
00279   {
00280     if (standAloneMsgWindow)
00281     {
00282       nsCOMPtr <nsIMsgFolder> folder;
00283       rv = GetExistingFolder(aFolderURI, getter_AddRefs(folder));
00284       NS_ENSURE_SUCCESS(rv, rv);
00285       nsXPIDLCString msgUri;
00286       folder->GetBaseMessageURI(getter_Copies(msgUri));
00287 
00288       nsCOMPtr<nsISupportsCString> scriptableMsgURI (do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
00289       NS_ENSURE_TRUE(scriptableMsgURI, NS_ERROR_FAILURE);
00290       msgUri.Append('#');
00291       msgUri.AppendInt(aMessageKey, 10);
00292       scriptableMsgURI->SetData(msgUri);
00293       argsArray->AppendElement(scriptableMsgURI);
00294       
00295     }
00296     nsCOMPtr<nsISupportsCString> scriptableFolderURI (do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
00297     NS_ENSURE_TRUE(scriptableFolderURI, NS_ERROR_FAILURE);
00298 
00299     scriptableFolderURI->SetData(nsDependentCString(aFolderURI));
00300     argsArray->AppendElement(scriptableFolderURI);
00301 
00302     if (!standAloneMsgWindow)
00303     {
00304       nsCOMPtr<nsISupportsPRUint32> scriptableMessageKey (do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID));
00305       NS_ENSURE_TRUE(scriptableMessageKey, NS_ERROR_FAILURE);
00306       scriptableMessageKey->SetData(aMessageKey);
00307       argsArray->AppendElement(scriptableMessageKey);
00308     }
00309   }
00310   
00311   nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv));
00312   NS_ENSURE_SUCCESS(rv, rv);
00313 
00314   // we need to use the "mailnews.reuse_thread_window2" pref
00315        // to determine if we should open a new window, or use an existing one.
00316   nsCOMPtr<nsIDOMWindow> newWindow;
00317   rv = wwatch->OpenWindow(0, chromeurl.get(), "_blank",
00318                  "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar,dialog=no",
00319                  argsArray,
00320                  getter_AddRefs(newWindow));
00321 
00322   return NS_OK;
00323 }