Back to index

lightning-sunbird  0.9+nobinonly
HelperAppDlg.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  *   Adam Lock <adamlock@eircom.net>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "stdafx.h"
00040 
00041 #include <commctrl.h>
00042 
00043 // commdlg.h is needed to build with WIN32_LEAN_AND_MEAN
00044 #include <commdlg.h>
00045 
00046 #include "HelperAppDlg.h"
00047 
00048 #include "nsCOMPtr.h"
00049 #include "nsIExternalHelperAppService.h"
00050 #include "nsILocalFile.h"
00051 #include "nsIMIMEInfo.h"
00052 
00053 #include "nsIHelperAppLauncherDialog.h"
00054 
00055 #include "nsNetError.h"
00056 
00057 
00059 
00060 class AppLauncherDlg
00061 {
00062 public:
00063     AppLauncherDlg();
00064     virtual ~AppLauncherDlg();
00065 
00066     int Show(nsIHelperAppLauncher* aLauncher, HWND hwndParent);
00067 
00068     PRPackedBool mSaveToDisk;
00069     nsCAutoString mOpenWith;
00070 
00071 private:
00072     static BOOL CALLBACK LaunchProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
00073 
00074     void OnInitDialog();
00075     void OnOK();
00076     void OnCancel();
00077     void OnChooseApp();
00078 
00079     HWND mHwndDlg;
00080     nsCOMPtr<nsIHelperAppLauncher> mHelperAppLauncher;
00081 };
00082 
00083 AppLauncherDlg::AppLauncherDlg() : mHwndDlg(NULL), mSaveToDisk(TRUE)
00084 {
00085 }
00086 
00087 AppLauncherDlg::~AppLauncherDlg()
00088 {
00089 }
00090 
00091 int
00092 AppLauncherDlg::Show(nsIHelperAppLauncher* aLauncher, HWND hwndParent)
00093 {
00094     HINSTANCE hInstResource = _Module.m_hInstResource;
00095 
00096     mHelperAppLauncher = aLauncher;
00097 
00098     INT result = DialogBoxParam(hInstResource,
00099         MAKEINTRESOURCE(IDD_HELPERAPP), hwndParent, LaunchProc, (LPARAM) this);
00100     
00101     return result;
00102 }
00103 
00104 void AppLauncherDlg::OnInitDialog()
00105 {
00106     USES_CONVERSION;
00107     nsCOMPtr<nsIMIMEInfo> mimeInfo;
00108     nsCAutoString url;
00109     if (mHelperAppLauncher)
00110     {
00111         mHelperAppLauncher->GetMIMEInfo(getter_AddRefs(mimeInfo));
00112         nsCOMPtr<nsIURI> uri;
00113         mHelperAppLauncher->GetSource(getter_AddRefs(uri));
00114         uri->GetSpec(url);
00115     }
00116     nsMIMEInfoHandleAction prefAction = nsIMIMEInfo::saveToDisk;
00117     nsAutoString appName;
00118     nsCAutoString contentType;
00119     if (mimeInfo)
00120     {
00121         mimeInfo->GetPreferredAction(&prefAction);
00122         mimeInfo->GetApplicationDescription(appName);
00123         mimeInfo->GetMIMEType(contentType);
00124     }
00125     if (prefAction == nsIMIMEInfo::saveToDisk)
00126     {
00127         CheckRadioButton(mHwndDlg, IDC_OPENWITHAPP, IDC_SAVETOFILE, IDC_SAVETOFILE);
00128     }
00129     else
00130     {
00131         CheckRadioButton(mHwndDlg, IDC_OPENWITHAPP, IDC_SAVETOFILE, IDC_OPENWITHAPP);
00132     }
00133     SetDlgItemText(mHwndDlg, IDC_URL,
00134         url.IsEmpty() ? _T("") : A2CT(url.get()));
00135     SetDlgItemText(mHwndDlg, IDC_APPLICATION,
00136         appName.IsEmpty() ? _T("<No Application>") : W2CT(appName.get()));
00137     SetDlgItemText(mHwndDlg, IDC_CONTENTTYPE,
00138         contentType.IsEmpty() ? _T("") : A2CT(contentType.get()));
00139 }
00140 
00141 void AppLauncherDlg::OnOK()
00142 {
00143     mSaveToDisk = IsDlgButtonChecked(mHwndDlg, IDC_SAVETOFILE) ? TRUE : FALSE;
00144     EndDialog(mHwndDlg, IDOK);
00145 }
00146 
00147 void AppLauncherDlg::OnCancel()
00148 {
00149     EndDialog(mHwndDlg, IDCANCEL);
00150 }
00151 
00152 void AppLauncherDlg::OnChooseApp()
00153 {
00154     USES_CONVERSION;
00155 
00156     TCHAR szPath[MAX_PATH + 1];
00157     memset(szPath, 0, sizeof(szPath));
00158 
00159     TCHAR *lpszFilter =
00160         _T("EXE Files Only (*.exe)\0*.exe\0"
00161            "All Files (*.*)\0*.*\0\0");
00162 
00163     OPENFILENAME ofn;
00164     memset(&ofn, 0, sizeof(ofn));
00165 #if _WIN32_WINNT >= 0x0500
00166     ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
00167 #else
00168     ofn.lStructSize = sizeof(ofn);
00169 #endif
00170     ofn.Flags = OFN_FILEMUSTEXIST;
00171     ofn.lpstrFilter = lpszFilter;
00172     ofn.lpstrDefExt = _T("exe");
00173     ofn.lpstrFile = szPath;
00174     ofn.nMaxFile = MAX_PATH;
00175 
00176     if (GetOpenFileName(&ofn))
00177     {
00178         USES_CONVERSION;
00179         mOpenWith = T2A(szPath);
00180         SetDlgItemText(mHwndDlg, IDC_APPLICATION, szPath);
00181         CheckRadioButton(mHwndDlg, IDC_OPENWITHAPP, IDC_SAVETOFILE, IDC_OPENWITHAPP);
00182     }
00183 }
00184 
00185 BOOL CALLBACK
00186 AppLauncherDlg::LaunchProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
00187 {
00188     AppLauncherDlg *pThis = NULL;
00189     if (uMsg == WM_INITDIALOG)
00190     {
00191         pThis = (AppLauncherDlg *) lParam;
00192         NS_WARN_IF_FALSE(pThis, "need a pointer to this!");
00193         pThis->mHwndDlg = hwndDlg;
00194         SetWindowLong(hwndDlg, DWL_USER, lParam);
00195     }
00196     else
00197     {
00198         pThis = (AppLauncherDlg *) GetWindowLong(hwndDlg, DWL_USER);
00199     }
00200     switch (uMsg)
00201     {
00202     case WM_INITDIALOG:
00203         pThis->OnInitDialog();
00204         return TRUE;
00205     case WM_COMMAND:
00206         if (HIWORD(wParam) == BN_CLICKED)
00207         {
00208             NS_WARN_IF_FALSE(pThis, "Should be non-null!");
00209             switch (LOWORD(wParam))
00210             {
00211             case IDC_CHOOSE:
00212                 pThis->OnChooseApp();
00213                 break;
00214             case IDOK:
00215                 pThis->OnOK();
00216                 break;
00217             case IDCANCEL:
00218                 pThis->OnCancel();
00219                 break;
00220             }
00221         }
00222         return TRUE;
00223     }
00224     return FALSE;
00225 }
00226 
00228 
00229 //*****************************************************************************
00230 // ProgressDlg
00231 //***************************************************************************** 
00232 
00233 
00234 class ProgressDlg :
00235      public nsIWebProgressListener,
00236      public nsSupportsWeakReference
00237 {
00238 public:
00239     ProgressDlg();
00240 
00241     void Show(nsIHelperAppLauncher *aHelperAppLauncher, HWND hwndParent);
00242 
00243 protected:
00244     virtual ~ProgressDlg();
00245 
00246     void OnInitDialog();
00247     void OnCancel();
00248 
00249     static BOOL CALLBACK ProgressProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
00250 
00251     HWND mHwndDlg;
00252     nsCOMPtr<nsIHelperAppLauncher> mHelperAppLauncher;
00253 
00254 public:
00255     NS_DECL_ISUPPORTS
00256     NS_DECL_NSIWEBPROGRESSLISTENER
00257 };
00258 
00259 
00260 ProgressDlg::ProgressDlg()
00261 {
00262 }
00263 
00264 ProgressDlg::~ProgressDlg() 
00265 {
00266 }
00267 
00268 void
00269 ProgressDlg::Show(nsIHelperAppLauncher *aHelperAppLauncher, HWND hwndParent)
00270 {
00271     HINSTANCE hInstResource = _Module.m_hInstResource;
00272 
00273     mHelperAppLauncher = aHelperAppLauncher;
00274     mHwndDlg = CreateDialogParam(hInstResource, MAKEINTRESOURCE(IDD_PROGRESS),
00275         hwndParent, ProgressProc, (LPARAM) this);
00276 }
00277 
00278 
00279 NS_IMPL_ISUPPORTS2(ProgressDlg, nsIWebProgressListener, nsISupportsWeakReference)
00280 
00281 NS_IMETHODIMP
00282 ProgressDlg::OnStateChange(nsIWebProgress *aWebProgress, 
00283                            nsIRequest *aRequest, PRUint32 aStateFlags, 
00284                            nsresult aStatus)
00285 {
00286     if ((aStateFlags & STATE_STOP) && (aStateFlags & STATE_IS_DOCUMENT))
00287     {
00288         // We've completed the download - close the progress window
00289         if(mHelperAppLauncher)
00290             mHelperAppLauncher->CloseProgressWindow();
00291 
00292         DestroyWindow(mHwndDlg);
00293     }
00294 
00295     return NS_OK;
00296 }
00297 
00298 NS_IMETHODIMP ProgressDlg::OnProgressChange(nsIWebProgress *aWebProgress, 
00299                                              nsIRequest *aRequest, 
00300                                              PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, 
00301                                              PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
00302 {
00303     // Update the progress control
00304     if (IsWindow(mHwndDlg))
00305     {
00306         HWND hwndProgress = GetDlgItem(mHwndDlg, IDC_PROGRESS);
00307         SendMessage(hwndProgress, PBM_SETRANGE32, 0, aMaxTotalProgress);
00308         SendMessage(hwndProgress, PBM_SETPOS, aCurTotalProgress, 0);
00309     }
00310 
00311     return NS_OK;
00312 }
00313 
00314 NS_IMETHODIMP ProgressDlg::OnLocationChange(nsIWebProgress *aWebProgress, 
00315                                              nsIRequest *aRequest, nsIURI *location)
00316 {
00317     return NS_OK;
00318 }
00319 
00320 NS_IMETHODIMP ProgressDlg::OnStatusChange(nsIWebProgress *aWebProgress, 
00321                                            nsIRequest *aRequest, nsresult aStatus, 
00322                                            const PRUnichar *aMessage)
00323 {
00324     return NS_OK;
00325 }
00326 
00327 NS_IMETHODIMP ProgressDlg::OnSecurityChange(nsIWebProgress *aWebProgress, 
00328                                              nsIRequest *aRequest, PRUint32 state)
00329 {
00330     return NS_OK;
00331 }
00332 
00334 
00335 BOOL CALLBACK
00336 ProgressDlg::ProgressProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
00337 {
00338     ProgressDlg *pThis = NULL;
00339     if (uMsg == WM_INITDIALOG)
00340     {
00341         pThis = (ProgressDlg *) lParam;
00342         SetWindowLong(hwndDlg, DWL_USER, lParam);
00343     }
00344     else
00345     {
00346         pThis = (ProgressDlg *) GetWindowLong(hwndDlg, DWL_USER);
00347     }
00348     switch (uMsg)
00349     {
00350     case WM_INITDIALOG:
00351         NS_WARN_IF_FALSE(pThis, "Should be non-null!");
00352         pThis->OnInitDialog();
00353         return TRUE;
00354     case WM_COMMAND:
00355         if (HIWORD(wParam) == BN_CLICKED)
00356         {
00357             NS_WARN_IF_FALSE(pThis, "Should be non-null!");
00358             switch (LOWORD(wParam))
00359             {
00360             case IDCANCEL:
00361                 pThis->OnCancel();
00362                 break;
00363             }
00364         }
00365         return TRUE;
00366     }
00367 
00368     return FALSE;
00369 }
00370 
00371 void ProgressDlg::OnInitDialog() 
00372 {
00373     // Set the "SavingFrom" field
00374     if (mHelperAppLauncher)
00375     {
00376         nsCOMPtr<nsIURI> srcUri;
00377         nsresult rv = mHelperAppLauncher->GetSource(getter_AddRefs(srcUri));
00378         if(NS_SUCCEEDED(rv))
00379         {
00380             USES_CONVERSION;
00381             nsCAutoString uriString;
00382             srcUri->GetSpec(uriString);
00383             SetDlgItemText(mHwndDlg, IDC_SOURCE, A2CT(uriString.get()));
00384         }
00385     }
00386 
00387     // Set the "Action" field
00388 //    if(m_HandleContentOp == CONTENT_SAVE_TO_DISK)
00389 //        m_Action.SetWindowText("[Saving file to:] " + m_FileName);
00390 //    else if(m_HandleContentOp == CONTENT_LAUNCH_WITH_APP)
00391 //        m_Action.SetWindowText("[Opening file with:] " + m_FileName);
00392 }
00393 
00394 void ProgressDlg::OnCancel() 
00395 {
00396     if (mHelperAppLauncher)
00397         mHelperAppLauncher->Cancel(NS_BINDING_ABORTED);
00398        DestroyWindow(mHwndDlg);
00399 }
00400 
00401 
00402 
00404 
00405 class CHelperAppLauncherDlgFactory : public nsIFactory
00406 {
00407 public:
00408     NS_DECL_ISUPPORTS
00409     NS_DECL_NSIFACTORY
00410 
00411     CHelperAppLauncherDlgFactory();
00412     virtual ~CHelperAppLauncherDlgFactory();
00413 };
00414 
00415 class CHelperAppLauncherDlg :
00416     public nsIHelperAppLauncherDialog
00417 {
00418 public:
00419     CHelperAppLauncherDlg();
00420 
00421 protected:
00422     virtual ~CHelperAppLauncherDlg();
00423 
00424 public:
00425     NS_DECL_ISUPPORTS
00426     NS_DECL_NSIHELPERAPPLAUNCHERDIALOG
00427 
00428     friend class CHelperAppLauncherDlgFactory;
00429 };
00430 
00431 NS_IMPL_ISUPPORTS1(CHelperAppLauncherDlg, nsIHelperAppLauncherDialog)
00432 
00433 CHelperAppLauncherDlg::CHelperAppLauncherDlg()
00434 {
00435 }
00436 
00437 CHelperAppLauncherDlg::~CHelperAppLauncherDlg() 
00438 {
00439 }
00440 
00441 /* void show (in nsIHelperAppLauncher aLauncher, in nsISupports aContext, in unsigned long aReason); */
00442 NS_IMETHODIMP
00443 CHelperAppLauncherDlg::Show(nsIHelperAppLauncher *aLauncher, nsISupports *aContext, PRUint32 aReason)
00444 {
00445     NS_ENSURE_ARG_POINTER(aLauncher);
00446     
00447     AppLauncherDlg dlg;
00448     if (dlg.Show(aLauncher, NULL) == IDCANCEL)
00449     {
00450         aLauncher->Cancel(NS_BINDING_ABORTED);
00451         return NS_OK;
00452     }
00453 
00454     if (dlg.mSaveToDisk)
00455     {
00456         return aLauncher->SaveToDisk(nsnull, PR_FALSE);
00457     }
00458     else
00459     {
00460         nsCOMPtr<nsILocalFile> openWith;
00461         nsresult rv = NS_NewNativeLocalFile(dlg.mOpenWith, PR_FALSE, getter_AddRefs(openWith));
00462         return aLauncher->LaunchWithApplication(openWith, PR_FALSE);
00463     }
00464 }
00465 
00466 /* nsILocalFile promptForSaveToFile (in nsIHelperAppLauncher aLauncher, in nsISupports aWindowContext, in wstring aDefaultFile, in wstring aSuggestedFileExtension); */
00467 NS_IMETHODIMP
00468 CHelperAppLauncherDlg::PromptForSaveToFile(nsIHelperAppLauncher *aLauncher, 
00469                                            nsISupports *aWindowContext, 
00470                                            const PRUnichar *aDefaultFile, 
00471                                            const PRUnichar *aSuggestedFileExtension, 
00472                                            nsILocalFile **_retval)
00473 {
00474     NS_ENSURE_ARG_POINTER(_retval);
00475     USES_CONVERSION;
00476 
00477     TCHAR szPath[MAX_PATH + 1];
00478     memset(szPath, 0, sizeof(szPath));
00479     _tcsncpy(szPath, W2T(aDefaultFile), MAX_PATH);
00480 
00481     OPENFILENAME ofn;
00482     memset(&ofn, 0, sizeof(ofn));
00483 #if _WIN32_WINNT >= 0x0500
00484     ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
00485 #else
00486     ofn.lStructSize = sizeof(ofn);
00487 #endif
00488     ofn.Flags = OFN_OVERWRITEPROMPT;
00489     ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0\0");
00490     ofn.lpstrDefExt = W2T(aSuggestedFileExtension);
00491     ofn.lpstrFile = szPath;
00492     ofn.nMaxFile = MAX_PATH;
00493 
00494     if (GetSaveFileName(&ofn))
00495     {
00496         return NS_NewNativeLocalFile(nsDependentCString(szPath), PR_FALSE, _retval);
00497     }
00498     
00499     return NS_ERROR_FAILURE;
00500 }
00501 
00502 //*****************************************************************************
00503 // CHelperAppLauncherDlgFactory
00504 //*****************************************************************************   
00505 
00506 NS_IMPL_ISUPPORTS1(CHelperAppLauncherDlgFactory, nsIFactory)
00507 
00508 CHelperAppLauncherDlgFactory::CHelperAppLauncherDlgFactory()
00509 {
00510 }
00511 
00512 CHelperAppLauncherDlgFactory::~CHelperAppLauncherDlgFactory()
00513 {
00514 }
00515 
00516 NS_IMETHODIMP CHelperAppLauncherDlgFactory::CreateInstance(nsISupports *aOuter, const nsIID & aIID, void **aResult)
00517 {
00518     NS_ENSURE_ARG_POINTER(aResult);
00519 
00520     *aResult = NULL;  
00521     CHelperAppLauncherDlg *inst = new CHelperAppLauncherDlg;    
00522     if (!inst)
00523     return NS_ERROR_OUT_OF_MEMORY;
00524 
00525     nsresult rv = inst->QueryInterface(aIID, aResult);
00526     if (rv != NS_OK) {  
00527         // We didn't get the right interface, so clean up  
00528         delete inst;  
00529     }  
00530     return rv;
00531 }
00532 
00533 NS_IMETHODIMP CHelperAppLauncherDlgFactory::LockFactory(PRBool lock)
00534 {
00535     return NS_OK;
00536 }
00537 
00538 nsresult NS_NewHelperAppLauncherDlgFactory(nsIFactory** aFactory)
00539 {
00540     NS_ENSURE_ARG_POINTER(aFactory);
00541     *aFactory = nsnull;
00542 
00543     CHelperAppLauncherDlgFactory *result = new CHelperAppLauncherDlgFactory;
00544     if (!result)
00545         return NS_ERROR_OUT_OF_MEMORY;
00546 
00547     NS_ADDREF(result);
00548     *aFactory = result;
00549 
00550     return NS_OK;
00551 }