mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 11:45:37 +00:00
3eb43cb01a
In content process, we should set nsIPrintSettings::IsCancelled to true in order to cancel the print job. nsPrintEngine use this flag for cancelling. MozReview-Commit-ID: EqnNJOlIm5s --HG-- extra : rebase_source : 500cd839e2e0926a19108d953532056871651af8
260 lines
8.5 KiB
C++
260 lines
8.5 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsPrintingProxy.h"
|
|
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
#include "mozilla/dom/ContentChild.h"
|
|
#include "mozilla/dom/TabChild.h"
|
|
#include "mozilla/layout/RemotePrintJobChild.h"
|
|
#include "mozilla/Unused.h"
|
|
#include "nsIDocShell.h"
|
|
#include "nsIDocShellTreeOwner.h"
|
|
#include "nsIPrintingPromptService.h"
|
|
#include "nsIPrintSession.h"
|
|
#include "nsPIDOMWindow.h"
|
|
#include "nsPrintOptionsImpl.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
#include "PrintDataUtils.h"
|
|
#include "PrintProgressDialogChild.h"
|
|
#include "PrintSettingsDialogChild.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
using namespace mozilla::embedding;
|
|
using namespace mozilla::layout;
|
|
|
|
static StaticRefPtr<nsPrintingProxy> sPrintingProxyInstance;
|
|
|
|
NS_IMPL_ISUPPORTS(nsPrintingProxy, nsIPrintingPromptService)
|
|
|
|
nsPrintingProxy::nsPrintingProxy()
|
|
{
|
|
}
|
|
|
|
nsPrintingProxy::~nsPrintingProxy()
|
|
{
|
|
}
|
|
|
|
/* static */
|
|
already_AddRefed<nsPrintingProxy>
|
|
nsPrintingProxy::GetInstance()
|
|
{
|
|
if (!sPrintingProxyInstance) {
|
|
sPrintingProxyInstance = new nsPrintingProxy();
|
|
if (!sPrintingProxyInstance) {
|
|
return nullptr;
|
|
}
|
|
nsresult rv = sPrintingProxyInstance->Init();
|
|
if (NS_FAILED(rv)) {
|
|
sPrintingProxyInstance = nullptr;
|
|
return nullptr;
|
|
}
|
|
ClearOnShutdown(&sPrintingProxyInstance);
|
|
}
|
|
|
|
RefPtr<nsPrintingProxy> inst = sPrintingProxyInstance.get();
|
|
return inst.forget();
|
|
}
|
|
|
|
nsresult
|
|
nsPrintingProxy::Init()
|
|
{
|
|
mozilla::Unused << ContentChild::GetSingleton()->SendPPrintingConstructor(this);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrintingProxy::ShowPrintDialog(mozIDOMWindowProxy *parent,
|
|
nsIWebBrowserPrint *webBrowserPrint,
|
|
nsIPrintSettings *printSettings)
|
|
{
|
|
NS_ENSURE_ARG(webBrowserPrint);
|
|
NS_ENSURE_ARG(printSettings);
|
|
|
|
// If parent is null we are just being called to retrieve the print settings
|
|
// from the printer in the parent for print preview.
|
|
TabChild* pBrowser = nullptr;
|
|
if (parent) {
|
|
// Get the TabChild for this nsIDOMWindow, which we can then pass up to
|
|
// the parent.
|
|
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
|
|
NS_ENSURE_STATE(pwin);
|
|
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
|
|
NS_ENSURE_STATE(docShell);
|
|
|
|
nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
|
|
NS_ENSURE_STATE(tabchild);
|
|
|
|
pBrowser = static_cast<TabChild*>(tabchild.get());
|
|
}
|
|
|
|
// Next, serialize the nsIWebBrowserPrint and nsIPrintSettings we were given.
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
|
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
PrintData inSettings;
|
|
rv = printSettingsSvc->SerializeToPrintData(printSettings, webBrowserPrint,
|
|
&inSettings);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Now, the waiting game. The parent process should be showing
|
|
// the printing dialog soon. In the meantime, we need to spin a
|
|
// nested event loop while we wait for the results of the dialog
|
|
// to be returned to us.
|
|
|
|
RefPtr<PrintSettingsDialogChild> dialog = new PrintSettingsDialogChild();
|
|
SendPPrintSettingsDialogConstructor(dialog);
|
|
|
|
mozilla::Unused << SendShowPrintDialog(dialog, pBrowser, inSettings);
|
|
|
|
SpinEventLoopUntil([&, dialog]() { return dialog->returned(); });
|
|
|
|
rv = dialog->result();
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = printSettingsSvc->DeserializeToPrintSettings(dialog->data(),
|
|
printSettings);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrintingProxy::ShowProgress(mozIDOMWindowProxy* parent,
|
|
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
|
|
nsIPrintSettings* printSettings, // ok to be null
|
|
nsIObserver* openDialogObserver, // ok to be null
|
|
bool isForPrinting,
|
|
nsIWebProgressListener** webProgressListener,
|
|
nsIPrintProgressParams** printProgressParams,
|
|
bool* notifyOnOpen)
|
|
{
|
|
NS_ENSURE_ARG(parent);
|
|
NS_ENSURE_ARG(webProgressListener);
|
|
NS_ENSURE_ARG(printProgressParams);
|
|
NS_ENSURE_ARG(notifyOnOpen);
|
|
|
|
// Get the TabChild for this nsIDOMWindow, which we can then pass up to
|
|
// the parent.
|
|
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
|
|
NS_ENSURE_STATE(pwin);
|
|
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
|
|
NS_ENSURE_STATE(docShell);
|
|
nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
|
|
TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
|
|
|
|
RefPtr<PrintProgressDialogChild> dialogChild =
|
|
new PrintProgressDialogChild(openDialogObserver, printSettings);
|
|
|
|
SendPPrintProgressDialogConstructor(dialogChild);
|
|
|
|
// Get the RemotePrintJob if we have one available.
|
|
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
|
if (printSettings) {
|
|
nsCOMPtr<nsIPrintSession> printSession;
|
|
nsresult rv = printSettings->GetPrintSession(getter_AddRefs(printSession));
|
|
if (NS_SUCCEEDED(rv) && printSession) {
|
|
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
|
}
|
|
}
|
|
|
|
// NOTE: We set notifyOnOpen to true unconditionally. If the parent process
|
|
// would get `false` for notifyOnOpen, then it will synthesize a notification
|
|
// which will be sent asynchronously down to the child.
|
|
*notifyOnOpen = true;
|
|
mozilla::Unused << SendShowProgress(pBrowser, dialogChild, remotePrintJob,
|
|
isForPrinting);
|
|
|
|
// If we have a RemotePrintJob that will be being used as a more general
|
|
// forwarder for print progress listeners. Once we always have one we can
|
|
// remove the interface from PrintProgressDialogChild.
|
|
if (!remotePrintJob) {
|
|
NS_ADDREF(*webProgressListener = dialogChild);
|
|
}
|
|
NS_ADDREF(*printProgressParams = dialogChild);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrintingProxy::ShowPageSetup(mozIDOMWindowProxy *parent,
|
|
nsIPrintSettings *printSettings,
|
|
nsIObserver *aObs)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
nsresult
|
|
nsPrintingProxy::SavePrintSettings(nsIPrintSettings* aPS,
|
|
bool aUsePrinterNamePrefix,
|
|
uint32_t aFlags)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
|
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
PrintData settings;
|
|
rv = printSettingsSvc->SerializeToPrintData(aPS, nullptr, &settings);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
Unused << SendSavePrintSettings(settings, aUsePrinterNamePrefix, aFlags,
|
|
&rv);
|
|
return rv;
|
|
}
|
|
|
|
PPrintProgressDialogChild*
|
|
nsPrintingProxy::AllocPPrintProgressDialogChild()
|
|
{
|
|
// The parent process will never initiate the PPrintProgressDialog
|
|
// protocol connection, so no need to provide an allocator here.
|
|
NS_NOTREACHED("Allocator for PPrintProgressDialogChild should not be "
|
|
"called on nsPrintingProxy.");
|
|
return nullptr;
|
|
}
|
|
|
|
bool
|
|
nsPrintingProxy::DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor)
|
|
{
|
|
// The PrintProgressDialogChild implements refcounting, and
|
|
// will take itself out.
|
|
return true;
|
|
}
|
|
|
|
PPrintSettingsDialogChild*
|
|
nsPrintingProxy::AllocPPrintSettingsDialogChild()
|
|
{
|
|
// The parent process will never initiate the PPrintSettingsDialog
|
|
// protocol connection, so no need to provide an allocator here.
|
|
NS_NOTREACHED("Allocator for PPrintSettingsDialogChild should not be "
|
|
"called on nsPrintingProxy.");
|
|
return nullptr;
|
|
}
|
|
|
|
bool
|
|
nsPrintingProxy::DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor)
|
|
{
|
|
// The PrintSettingsDialogChild implements refcounting, and
|
|
// will take itself out.
|
|
return true;
|
|
}
|
|
|
|
PRemotePrintJobChild*
|
|
nsPrintingProxy::AllocPRemotePrintJobChild()
|
|
{
|
|
RefPtr<RemotePrintJobChild> remotePrintJob = new RemotePrintJobChild();
|
|
return remotePrintJob.forget().take();
|
|
}
|
|
|
|
bool
|
|
nsPrintingProxy::DeallocPRemotePrintJobChild(PRemotePrintJobChild* aDoomed)
|
|
{
|
|
RemotePrintJobChild* remotePrintJob = static_cast<RemotePrintJobChild*>(aDoomed);
|
|
NS_RELEASE(remotePrintJob);
|
|
return true;
|
|
}
|