Back to index

lightning-sunbird  0.9+nobinonly
PrintingPromptService.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: Mozilla-sample-code 1.0
00004  *
00005  * Copyright (c) 2002 Netscape Communications Corporation and
00006  * other contributors
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a
00009  * copy of this Mozilla sample software and associated documentation files
00010  * (the "Software"), to deal in the Software without restriction, including
00011  * without limitation the rights to use, copy, modify, merge, publish,
00012  * distribute, sublicense, and/or sell copies of the Software, and to permit
00013  * persons to whom the Software is furnished to do so, subject to the
00014  * following conditions:
00015  *
00016  * The above copyright notice and this permission notice shall be included
00017  * in all copies or substantial portions of the Software.
00018  *
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00020  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00022  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00024  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00025  * DEALINGS IN THE SOFTWARE.
00026  *
00027  * Contributor(s):
00028  *
00029  * ***** END LICENSE BLOCK ***** */
00030 
00031 /* PrintingPromptService is intended to override the default Mozilla PrintingPromptService,
00032    giving nsIPrompt implementations of our own design, rather than using
00033    Mozilla's. Do this by building this into a component and registering the
00034    factory with the same CID/ContractID as Mozilla's (see MfcEmbed.cpp).
00035 */
00036 
00037 #include "stdafx.h"
00038 #include "Dialogs.h"
00039 #include "PrintingPromptService.h"
00040 #include "nsCOMPtr.h"
00041 #include "nsMemory.h"
00042 #include "nsString.h"
00043 #include "nsReadableUtils.h"
00044 #include "nsIDOMWindow.h"
00045 #include "nsIEmbeddingSiteWindow.h"
00046 #include "nsIFactory.h"
00047 #include "nsIPrintingPromptService.h"
00048 #include "nsIServiceManager.h"
00049 #include "nsIWebBrowserChrome.h"
00050 #include "nsIWindowWatcher.h"
00051 #include "nsIWebProgressListener.h"
00052 #include "nsPrintProgressParams.h"
00053 #include "nsPrintDialogUtil.h"
00054 #include "PrintProgressDialog.h"
00055 
00056 // For PLEvent
00057 #include "nsIEventQueueService.h"
00058 #include "plevent.h"
00059 
00060 static HINSTANCE gInstance;
00061 
00062 //*****************************************************************************
00063 // ResourceState
00064 //***************************************************************************** 
00065 
00066 class ResourceState {
00067 public:
00068   ResourceState() {
00069     mPreviousInstance = ::AfxGetResourceHandle();
00070     ::AfxSetResourceHandle(gInstance);
00071   }
00072   ~ResourceState() {
00073     ::AfxSetResourceHandle(mPreviousInstance);
00074   }
00075 private:
00076   HINSTANCE mPreviousInstance;
00077 };
00078 
00079 
00080 //*****************************************************************************
00081 // CPrintingPromptService
00082 //*****************************************************************************
00083 
00084 class CPrintingPromptService: public nsIPrintingPromptService,
00085                               public nsIWebProgressListener {
00086 public:
00087                  CPrintingPromptService();
00088   virtual       ~CPrintingPromptService();
00089 
00090   NS_DECL_ISUPPORTS
00091   NS_DECL_NSIPRINTINGPROMPTSERVICE
00092   NS_DECL_NSIWEBPROGRESSLISTENER
00093 
00094   void NotifyObserver();
00095 
00096 private:
00097   PRBool FirePauseEvent();
00098   CWnd *CWndForDOMWindow(nsIDOMWindow *aWindow);
00099 
00100   nsCOMPtr<nsIWindowWatcher>       mWWatch;
00101   nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
00102   nsCOMPtr<nsIObserver>            mObserver;
00103   CPrintProgressDialog* m_PPDlg;
00104 };
00105 
00106 // Define PL Callback Functions
00107 static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
00108 static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
00109 
00110 
00111 //*****************************************************************************
00112 
00113 NS_IMPL_ISUPPORTS2(CPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
00114 
00115 CPrintingPromptService::CPrintingPromptService() :
00116   mWWatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)),
00117   m_PPDlg(NULL)
00118 {
00119 }
00120 
00121 CPrintingPromptService::~CPrintingPromptService() {
00122 }
00123 
00124 CWnd *
00125 CPrintingPromptService::CWndForDOMWindow(nsIDOMWindow *aWindow)
00126 {
00127   nsCOMPtr<nsIWebBrowserChrome> chrome;
00128   CWnd *val = 0;
00129 
00130   if (mWWatch) {
00131     nsCOMPtr<nsIDOMWindow> fosterParent;
00132     if (!aWindow) { // it will be a dependent window. try to find a foster parent.
00133       mWWatch->GetActiveWindow(getter_AddRefs(fosterParent));
00134       aWindow = fosterParent;
00135     }
00136     mWWatch->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
00137   }
00138 
00139   if (chrome) {
00140     nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
00141     if (site) {
00142       HWND w;
00143       site->GetSiteWindow(reinterpret_cast<void **>(&w));
00144       val = CWnd::FromHandle(w);
00145     }
00146   }
00147 
00148   return val;
00149 }
00150 
00152 // nsIPrintingPrompt
00153 
00154 //-----------------------------------------------------------
00155 NS_IMETHODIMP 
00156 CPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
00157 {
00158     //NS_ENSURE_ARG(parent);
00159 
00160     CWnd* wnd = CWndForDOMWindow(parent);
00161 
00162     NS_ASSERTION(wnd && wnd->m_hWnd, "Couldn't get native window for PRint Dialog!");
00163     if (wnd && wnd->m_hWnd) {
00164       return NativeShowPrintDialog(wnd->m_hWnd, webBrowserPrint, printSettings);
00165     } else {
00166       return NS_ERROR_FAILURE;
00167     }
00168 }
00169 
00170 
00171 //-----------------------------------------------------------
00172 PRBool
00173 CPrintingPromptService::FirePauseEvent()
00174 {
00175   static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
00176 
00177   nsCOMPtr<nsIEventQueueService> event_service = do_GetService(kEventQueueServiceCID);
00178 
00179   if (!event_service) 
00180   {
00181     NS_WARNING("Failed to get event queue service");
00182     return PR_FALSE;
00183   }
00184 
00185   nsCOMPtr<nsIEventQueue> event_queue;
00186 
00187   event_service->GetThreadEventQueue(NS_CURRENT_THREAD,
00188                                      getter_AddRefs(event_queue));
00189 
00190   if (!event_queue) 
00191   {
00192     NS_WARNING("Failed to get event queue from service");
00193     return PR_FALSE;
00194   }
00195 
00196   PLEvent *event = new PLEvent;
00197 
00198   if (!event) 
00199   {
00200     NS_WARNING("Out of memory?");
00201     return PR_FALSE;
00202   }
00203 
00204   PL_InitEvent(event, this, (PLHandleEventProc)::HandlePLEvent, (PLDestroyEventProc)::DestroyPLEvent);
00205 
00206   // The event owns the content pointer now.
00207   NS_ADDREF_THIS();
00208 
00209   event_queue->PostEvent(event);
00210   return PR_TRUE;
00211 }
00212 
00213 /* void showProgress (in nsIDOMWindow parent, in nsIWebBrowserPrint webBrowserPrint, in nsIPrintSettings printSettings, in nsIObserver openDialogObserver, in boolean isForPrinting, out nsIWebProgressListener webProgressListener, out nsIPrintProgressParams printProgressParams, out boolean notifyOnOpen); */
00214 NS_IMETHODIMP 
00215 CPrintingPromptService::ShowProgress(nsIDOMWindow*            parent, 
00216                                       nsIWebBrowserPrint*      webBrowserPrint,    // ok to be null
00217                                       nsIPrintSettings*        printSettings,      // ok to be null
00218                                       nsIObserver*             openDialogObserver, // ok to be null
00219                                       PRBool                   isForPrinting,
00220                                       nsIWebProgressListener** webProgressListener,
00221                                       nsIPrintProgressParams** printProgressParams,
00222                                       PRBool*                  notifyOnOpen)
00223 {
00224     NS_ENSURE_ARG(webProgressListener);
00225     NS_ENSURE_ARG(printProgressParams);
00226     NS_ENSURE_ARG(notifyOnOpen);
00227 
00228     ResourceState setState;
00229     nsresult rv;
00230 
00231     nsPrintProgressParams* prtProgressParams = new nsPrintProgressParams();
00232     rv = prtProgressParams->QueryInterface(NS_GET_IID(nsIPrintProgressParams), (void**)printProgressParams);
00233     NS_ENSURE_SUCCESS(rv, rv);
00234 
00235     mObserver = openDialogObserver;
00236 
00237     *notifyOnOpen = PR_FALSE;
00238     if (printProgressParams) 
00239     {
00240       CWnd *wnd = CWndForDOMWindow(parent);
00241       m_PPDlg = new CPrintProgressDialog(wnd, isForPrinting, *printProgressParams, webBrowserPrint, printSettings);
00242       m_PPDlg->Create(IDD_PRINT_PROGRESS_DIALOG);
00243       m_PPDlg->ShowWindow(SW_SHOW);
00244       m_PPDlg->UpdateWindow();
00245 
00246       *notifyOnOpen = FirePauseEvent();
00247     }
00248 
00249     *webProgressListener = NS_STATIC_CAST(nsIWebProgressListener*, this);
00250     NS_ADDREF(*webProgressListener);
00251 
00252     return rv;
00253 }
00254 
00255 /* void showPageSetup (in nsIDOMWindow parent, in nsIPrintSettings printSettings); */
00256 NS_IMETHODIMP 
00257 CPrintingPromptService::ShowPageSetup(nsIDOMWindow *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
00258 {
00259     NS_ENSURE_ARG(printSettings);
00260 
00261     return NS_ERROR_NOT_IMPLEMENTED;
00262 }
00263 
00264 /* void showPrinterProperties (in nsIDOMWindow parent, in wstring printerName, in nsIPrintSettings printSettings); */
00265 NS_IMETHODIMP 
00266 CPrintingPromptService::ShowPrinterProperties(nsIDOMWindow *parent, const PRUnichar *printerName, nsIPrintSettings *printSettings)
00267 {
00268     return NS_ERROR_NOT_IMPLEMENTED;
00269 }
00270 
00271 //------------------------------------------------------------------------
00272 void CPrintingPromptService::NotifyObserver()
00273 {
00274   if (mObserver) {
00275     mObserver->Observe(nsnull, nsnull, nsnull);
00276   }
00277 }
00278 
00279 //------------------------------------------------------------------------
00280 void PR_CALLBACK HandlePLEvent(PLEvent* aEvent)
00281 {
00282   CPrintingPromptService *printingPromptService = (CPrintingPromptService*)PL_GetEventOwner(aEvent);
00283 
00284   NS_ASSERTION(printingPromptService, "The event owner is null.");
00285   if (printingPromptService) {
00286     printingPromptService->NotifyObserver();
00287   }
00288 }
00289 
00290 //------------------------------------------------------------------------
00291 void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent)
00292 {
00293   CPrintingPromptService *printingPromptService = (CPrintingPromptService*)PL_GetEventOwner(aEvent);
00294   NS_IF_RELEASE(printingPromptService);
00295 
00296   delete aEvent;
00297 }
00298 
00300 // nsIWebProgressListener
00302 
00303 /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in nsresult aStatus); */
00304 NS_IMETHODIMP 
00305 CPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
00306 {
00307     if (aStateFlags & STATE_START) 
00308     {
00309       if (m_PPDlg)
00310       {
00311         m_PPDlg->OnStartPrinting();
00312       }
00313     }
00314 
00315     if (aStateFlags & STATE_STOP) 
00316     {
00317       if (m_PPDlg)
00318       {
00319         m_PPDlg->OnProgressPrinting(100, 100);
00320         m_PPDlg->DestroyWindow();
00321         m_PPDlg = NULL;
00322       }
00323     }
00324     return NS_OK;
00325 }
00326 
00327 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
00328 NS_IMETHODIMP 
00329 CPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
00330 {
00331     if (m_PPDlg)
00332     {
00333       m_PPDlg->OnProgressPrinting(aCurTotalProgress, aMaxTotalProgress);
00334     }
00335     return NS_OK;
00336 }
00337 
00338 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
00339 NS_IMETHODIMP 
00340 CPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
00341 {
00342     return NS_OK;
00343 }
00344 
00345 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
00346 NS_IMETHODIMP 
00347 CPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
00348 {
00349     return NS_OK;
00350 }
00351 
00352 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
00353 NS_IMETHODIMP 
00354 CPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
00355 {
00356     return NS_OK;
00357 }
00358 
00359 
00360  
00361 //*****************************************************************************
00362 // CPrintingPromptServiceFactory
00363 //*****************************************************************************   
00364 
00365 class CPrintingPromptServiceFactory : public nsIFactory {
00366 public:
00367   NS_DECL_ISUPPORTS
00368   NS_DECL_NSIFACTORY
00369 
00370   CPrintingPromptServiceFactory();
00371   virtual ~CPrintingPromptServiceFactory();
00372 };
00373 
00374 //*****************************************************************************
00375 
00376 NS_IMPL_ISUPPORTS1(CPrintingPromptServiceFactory, nsIFactory)
00377 
00378 CPrintingPromptServiceFactory::CPrintingPromptServiceFactory() {
00379 }
00380 
00381 CPrintingPromptServiceFactory::~CPrintingPromptServiceFactory() {
00382 }
00383 
00384 NS_IMETHODIMP CPrintingPromptServiceFactory::CreateInstance(nsISupports *aOuter, const nsIID & aIID, void **aResult)
00385 {
00386   NS_ENSURE_ARG_POINTER(aResult);
00387   
00388   *aResult = NULL;  
00389   CPrintingPromptService *inst = new CPrintingPromptService;    
00390   if (!inst)
00391     return NS_ERROR_OUT_OF_MEMORY;
00392     
00393   nsresult rv = inst->QueryInterface(aIID, aResult);
00394   if (rv != NS_OK) {  
00395     // We didn't get the right interface, so clean up  
00396     delete inst;  
00397   }  
00398     
00399   return rv;
00400 }
00401 
00402 NS_IMETHODIMP CPrintingPromptServiceFactory::LockFactory(PRBool lock)
00403 {
00404   return NS_OK;
00405 }
00406 
00407 //*****************************************************************************
00408 
00409 void InitPrintingPromptService(HINSTANCE instance) {
00410 
00411   gInstance = instance;
00412 }
00413 
00414 nsresult NS_NewPrintingPromptServiceFactory(nsIFactory** aFactory)
00415 {
00416   NS_ENSURE_ARG_POINTER(aFactory);
00417   *aFactory = nsnull;
00418   
00419   CPrintingPromptServiceFactory *result = new CPrintingPromptServiceFactory;
00420   if (!result)
00421     return NS_ERROR_OUT_OF_MEMORY;
00422     
00423   NS_ADDREF(result);
00424   *aFactory = result;
00425   
00426   return NS_OK;
00427 }