1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Mozilla Public License Version
6
* 1.1 (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/MPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
23
* Rod Spears <rods@netscape.com>
24
* Don Cone <dcone@netscape.com>
25
* Conrad Carlen <ccarlen@netscape.com>
27
* Alternatively, the contents of this file may be used under the terms of
28
* either the GNU General Public License Version 2 or later (the "GPL"), or
29
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
* in which case the provisions of the GPL or the LGPL are applicable instead
31
* of those above. If you wish to allow use of your version of this file only
32
* under the terms of either the GPL or the LGPL, and not to allow others to
33
* use your version of this file under the terms of the MPL, indicate your
34
* decision by deleting the provisions above and replace them with the notice
35
* and other provisions required by the GPL or the LGPL. If you do not delete
36
* the provisions above, a recipient may use your version of this file under
37
* the terms of any one of the MPL, the GPL or the LGPL.
39
* ***** END LICENSE BLOCK ***** */
41
#include "nsPrintingPromptService.h"
45
#include "nsIPrintingPromptService.h"
46
#include "nsIFactory.h"
47
#include "nsIDOMWindow.h"
48
#include "nsReadableUtils.h"
49
#include "nsIEmbeddingSiteWindow.h"
50
#include "nsIServiceManager.h"
51
#include "nsIWebBrowserChrome.h"
52
#include "nsIWindowWatcher.h"
53
#include "nsIPrintSettingsMac.h"
54
#include "nsComponentResContext.h"
55
#include "nsWatchTask.h"
57
// Printing Progress Includes
58
#include "nsPrintProgress.h"
59
#include "nsPrintProgressParams.h"
60
#include "nsIWebProgressListener.h"
65
#include <Appearance.h>
66
#include <Resources.h>
69
static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul";
71
//-----------------------------------------------------------------------------
72
// Dialog Extension Code
73
//-----------------------------------------------------------------------------
77
// items to support the additional items for the dialog
78
#define DITL_ADDITIONS 128
81
ePrintSelectionCheckboxID = 1,
82
ePrintFrameAsIsCheckboxID,
83
ePrintSelectedFrameCheckboxID,
84
ePrintAllFramesCheckboxID,
88
typedef struct dialog_item_struct {
89
Handle handle; // handle or procedure pointer for this item */
90
Rect bounds; // display rectangle for this item */
91
char type; // item type - 1 */
92
char data[1]; // length byte of data */
93
} DialogItem, *DialogItemPtr, **DialogItemHandle;
95
typedef struct append_item_list_struct {
96
short max_index; // number of items - 1
97
DialogItem items[1]; // first item in the array
98
} ItemList, *ItemListPtr, **ItemListHandle;
100
// Static Variables - used by the dialog callbacks - no choice but globals
102
//static pascal TPPrDlg MyJobDlgInit(THPrint); // Our extention to PrJobInit
103
static TPPrDlg gPrtJobDialog; // pointer to job dialog
104
static long prFirstItem; // our first item in the extended dialog
105
static PItemUPP prPItemProc; // store the old item handler here
106
static PRBool gPrintSelection;
107
static PItemUPP gPrtJobDialogItemProc;
108
static UserItemUPP gDrawListUPP = nsnull;
109
static nsIPrintSettings *gPrintSettings = nsnull;
113
/** -------------------------------------------------------
114
* this is a drawing procedure for the user item.. this draws a box around the frameset radio buttons
115
* @update dc 12/02/98
117
static pascal void MyBBoxDraw(WindowPtr theWindow, short aItemNo)
123
::GetDialogItem((DialogPtr)gPrtJobDialog, prFirstItem + eDrawFrameID-1, &itemType, &itemH, &itemBox);
125
// use appearance if possible
126
if ((long)DrawThemeSecondaryGroup != kUnresolvedCFragSymbolAddress)
127
::DrawThemeSecondaryGroup(&itemBox, kThemeStateActive);
129
::FrameRect(&itemBox);
133
/** -------------------------------------------------------
134
* this is the dialog hook, takes care of setting the dialog items
135
* @update dc 12/02/98
137
static pascal void MyJobItems(DialogPtr aDialog, short aItemNo)
139
short myItem, firstItem, i, itemType;
144
firstItem = prFirstItem;
146
myItem = aItemNo-firstItem+1;
149
case ePrintSelectionCheckboxID:
150
::GetDialogItem(aDialog, firstItem, &itemType, &itemH, &itemBox);
151
gPrintSelection = !gPrintSelection;
152
::SetControlValue((ControlHandle)itemH, gPrintSelection);
155
case ePrintFrameAsIsCheckboxID:
156
case ePrintSelectedFrameCheckboxID:
157
case ePrintAllFramesCheckboxID:
158
for (i=ePrintFrameAsIsCheckboxID; i<=ePrintAllFramesCheckboxID; i++){
159
::GetDialogItem(aDialog, firstItem+i-1, &itemType, &itemH, &itemBox);
160
::SetControlValue((ControlHandle)itemH, i==myItem);
168
// chain to standard Item handler
169
CallPItemProc(prPItemProc, aDialog, aItemNo);
171
if (((TPPrDlg)aDialog)->fDone)
173
// cleanup and set the print options to what we want
177
::GetDialogItem(aDialog, firstItem+ePrintSelectionCheckboxID-1, &itemType, &itemH, &itemBox);
178
value = ::GetControlValue((ControlHandle)itemH);
180
gPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection);
182
gPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
185
// print frames as is
186
::GetDialogItem(aDialog, firstItem+ePrintFrameAsIsCheckboxID-1, &itemType, &itemH, &itemBox);
187
value = ::GetControlValue((ControlHandle)itemH);
189
gPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
193
::GetDialogItem(aDialog, firstItem+ePrintSelectedFrameCheckboxID-1, &itemType, &itemH, &itemBox);
194
value = ::GetControlValue((ControlHandle)itemH);
196
gPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);
200
::GetDialogItem(aDialog, firstItem+ePrintAllFramesCheckboxID-1, &itemType, &itemH, &itemBox);
201
value = ::GetControlValue((ControlHandle)itemH);
203
gPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
210
/** -------------------------------------------------------
211
* Append DITL items to the dialog
212
* @update dc 05/04/2001
214
static PRInt32 AppendToDialog(TPPrDlg aDialog, PRInt32 aDITLID)
217
ItemListHandle myAppendDITLH;
218
ItemListHandle dlg_Item_List;
220
dlg_Item_List = (ItemListHandle)((DialogPeek)aDialog)->items;
221
firstItem = (**dlg_Item_List).max_index+2;
223
nsComponentResourceContext resContext;
224
if (resContext.BecomeCurrent()) { // destructor restores
225
myAppendDITLH = (ItemListHandle)::GetResource('DITL', aDITLID);
226
NS_ASSERTION(myAppendDITLH, "Failed to get DITL items");
228
::AppendDITL((DialogPtr)aDialog, (Handle)myAppendDITLH, appendDITLBottom);
229
::ReleaseResource((Handle) myAppendDITLH);
237
/** -------------------------------------------------------
238
* Initialize the print dialogs additional items
239
* @update dc 05/04/2001
241
static pascal TPPrDlg MyJobDlgInit(THPrint aHPrint)
248
PRInt16 howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone;
250
prFirstItem = AppendToDialog(gPrtJobDialog, DITL_ADDITIONS);
252
if (gPrintSettings) {
253
gPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn);
254
gPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI);
257
::GetDialogItem((DialogPtr) gPrtJobDialog, prFirstItem+ePrintSelectionCheckboxID-1, &itemType, &itemH, &itemBox);
259
::HiliteControl((ControlHandle)itemH, 0);
261
::HiliteControl((ControlHandle)itemH, 255);
264
gPrintSelection = PR_FALSE;
265
::SetControlValue((ControlHandle) itemH, gPrintSelection);
267
if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) {
268
for (i = ePrintFrameAsIsCheckboxID; i <= ePrintAllFramesCheckboxID; i++){
269
::GetDialogItem((DialogPtr) gPrtJobDialog, prFirstItem+i-1, &itemType, &itemH, &itemBox);
270
::SetControlValue((ControlHandle) itemH, (i==4));
271
::HiliteControl((ControlHandle)itemH, 0);
274
else if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableAsIsAndEach) {
275
for (i = ePrintFrameAsIsCheckboxID; i <= ePrintAllFramesCheckboxID; i++){
276
::GetDialogItem((DialogPtr) gPrtJobDialog, prFirstItem+i-1, &itemType, &itemH, &itemBox);
277
::SetControlValue((ControlHandle) itemH, (i==4));
279
::HiliteControl((ControlHandle)itemH, 255);
284
for (i = ePrintFrameAsIsCheckboxID; i <= ePrintAllFramesCheckboxID; i++){
285
::GetDialogItem((DialogPtr) gPrtJobDialog, prFirstItem+i-1, &itemType, &itemH, &itemBox);
286
::SetControlValue((ControlHandle) itemH, FALSE);
287
::HiliteControl((ControlHandle)itemH, 255);
291
// attach our handler
292
prPItemProc = gPrtJobDialog->pItemProc;
293
gPrtJobDialog->pItemProc = gPrtJobDialogItemProc = NewPItemUPP(MyJobItems);
296
// attach a draw routine
297
gDrawListUPP = NewUserItemProc(MyBBoxDraw);
298
::GetDialogItem((DialogPtr)gPrtJobDialog, prFirstItem+eDrawFrameID-1, &itemType, &itemH, &itemBox);
299
::SetDialogItem((DialogPtr)gPrtJobDialog, prFirstItem+eDrawFrameID-1, itemType, (Handle)gDrawListUPP, &itemBox);
301
return gPrtJobDialog;
305
//*****************************************************************************
306
// nsPrintingPromptService
307
//*****************************************************************************
309
NS_IMPL_ISUPPORTS2(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
311
nsPrintingPromptService::nsPrintingPromptService() :
312
mWatcher(do_GetService(NS_WINDOWWATCHER_CONTRACTID))
316
nsPrintingPromptService::~nsPrintingPromptService()
320
nsresult nsPrintingPromptService::Init()
325
//*****************************************************************************
326
// nsPrintingPromptService::nsIPrintingPromptService
327
//*****************************************************************************
330
nsPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
332
THPrint printRecH = nsnull; // local copy of nsIPrintSettingsMac's data
334
PDlgInitUPP theInitProcPtr;
336
gPrintSettings = printSettings;
341
nsCOMPtr<nsIPrintSettingsMac> printSettingsMac(do_QueryInterface(printSettings));
342
if (!printSettingsMac)
343
return NS_ERROR_NO_INTERFACE;
345
theInitProcPtr = NewPDlgInitProc(MyJobDlgInit);
347
return NS_ERROR_FAILURE;
349
// Get the print record from the settings
350
rv = printSettingsMac->GetTHPrint(&printRecH);
354
// open the printing manager
356
if (::PrError() != noErr) {
357
::DisposeHandle((Handle)printRecH);
358
return NS_ERROR_FAILURE;
361
// make sure the print record is valid
362
::PrValidate(printRecH);
363
if (::PrError() != noErr) {
364
::DisposeHandle((Handle)printRecH);
366
return NS_ERROR_FAILURE;
369
// get pointer to invisible job dialog box
370
gPrtJobDialog = ::PrJobInit(printRecH);
371
if (::PrError() != noErr) {
372
::DisposeHandle((Handle)printRecH);
374
return NS_ERROR_FAILURE;
377
// create a UUP for the dialog init procedure
378
theInitProcPtr = NewPDlgInitProc(MyJobDlgInit);
380
return NS_ERROR_FAILURE;
382
nsWatchTask::GetTask().Suspend();
385
// put up the print dialog
386
if (::PrDlgMain(printRecH, theInitProcPtr))
388
// have the print record
390
printSettingsMac->SetTHPrint(printRecH);
399
::DisposeHandle((Handle)printRecH);
401
// clean up our dialog routines
402
DisposePItemUPP(gPrtJobDialogItemProc);
403
gPrtJobDialogItemProc = nsnull;
405
DisposePItemUPP(theInitProcPtr);
406
DisposePItemUPP(gDrawListUPP);
407
gDrawListUPP = nsnull;
409
nsWatchTask::GetTask().Resume();
414
nsPrintingPromptService::ShowProgress(nsIDOMWindow* parent,
415
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
416
nsIPrintSettings* printSettings, // ok to be null
417
nsIObserver* openDialogObserver, // ok to be null
418
PRBool isForPrinting,
419
nsIWebProgressListener** webProgressListener,
420
nsIPrintProgressParams** printProgressParams,
421
PRBool* notifyOnOpen)
423
NS_ENSURE_ARG(webProgressListener);
424
NS_ENSURE_ARG(printProgressParams);
425
NS_ENSURE_ARG(notifyOnOpen);
427
*notifyOnOpen = PR_FALSE;
429
nsPrintProgress* prtProgress = new nsPrintProgress();
430
nsresult rv = prtProgress->QueryInterface(NS_GET_IID(nsIPrintProgress), (void**)getter_AddRefs(mPrintProgress));
431
NS_ENSURE_SUCCESS(rv, rv);
433
rv = prtProgress->QueryInterface(NS_GET_IID(nsIWebProgressListener), (void**)getter_AddRefs(mWebProgressListener));
434
NS_ENSURE_SUCCESS(rv, rv);
436
nsPrintProgressParams* prtProgressParams = new nsPrintProgressParams();
437
rv = prtProgressParams->QueryInterface(NS_GET_IID(nsIPrintProgressParams), (void**)printProgressParams);
438
NS_ENSURE_SUCCESS(rv, rv);
440
if (printProgressParams)
444
nsCOMPtr<nsIDOMWindow> active;
445
mWatcher->GetActiveWindow(getter_AddRefs(active));
446
nsCOMPtr<nsIDOMWindowInternal> parent(do_QueryInterface(active));
447
mPrintProgress->OpenProgressDialog(parent, kPrintProgressDialogURL, *printProgressParams, openDialogObserver, notifyOnOpen);
451
*webProgressListener = static_cast<nsIWebProgressListener*>(this);
452
NS_ADDREF(*webProgressListener);
458
nsPrintingPromptService::ShowPageSetup(nsIDOMWindow *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
460
nsCOMPtr<nsIPrintSettingsMac> printSettingsMac(do_QueryInterface(printSettings));
461
if (!printSettingsMac)
462
return NS_ERROR_NO_INTERFACE;
464
// open the printing manager
466
if(::PrError() != noErr)
467
return NS_ERROR_FAILURE;
472
rv = printSettingsMac->GetTHPrint(&printRecH);
476
::PrValidate(printRecH);
477
NS_ASSERTION(::PrError() == noErr, "PrValidate error");
479
nsWatchTask::GetTask().Suspend();
481
Boolean dialogOK = ::PrStlDialog(printRecH); // open up and process the style record
482
nsWatchTask::GetTask().Resume();
484
OSErr err = ::PrError();
488
rv = printSettingsMac->SetTHPrint(printRecH);
491
return NS_ERROR_FAILURE;
493
return NS_ERROR_ABORT;
499
nsPrintingPromptService::ShowPrinterProperties(nsIDOMWindow *parent, const PRUnichar *printerName, nsIPrintSettings *printSettings)
501
return NS_ERROR_NOT_IMPLEMENTED;
504
//*****************************************************************************
505
// nsPrintingPromptService::nsIWebProgressListener
506
//*****************************************************************************
509
nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
511
if ((aStateFlags & STATE_STOP) && mWebProgressListener)
513
mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
516
mPrintProgress->CloseProgressDialog(PR_TRUE);
518
mPrintProgress = nsnull;
519
mWebProgressListener = nsnull;
524
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
526
nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
528
if (mWebProgressListener) {
529
return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
534
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
536
nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
538
if (mWebProgressListener) {
539
return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location);
544
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
546
nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
548
if (mWebProgressListener) {
549
return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
554
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
556
nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
558
if (mWebProgressListener) {
559
return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state);