mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1189846 Part 9: Add ability to print from the parent process with settings and progress listener. r=jimm, r=smaug
MozReview-Commit-ID: 7IEMByPmC0n
This commit is contained in:
parent
80ef8208d0
commit
2d161a3465
@ -103,6 +103,11 @@
|
||||
#include "nsXULPopupManager.h"
|
||||
#endif
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
#include "mozilla/embedding/printingui/PrintingParent.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::dom;
|
||||
@ -3102,6 +3107,46 @@ nsFrameLoader::RequestNotifyLayerTreeCleared()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::Print(nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aProgressListener)
|
||||
{
|
||||
#if defined(NS_PRINTING)
|
||||
if (mRemoteBrowser) {
|
||||
RefPtr<embedding::PrintingParent> printingParent =
|
||||
mRemoteBrowser->Manager()->AsContentParent()->GetPrintingParent();
|
||||
|
||||
embedding::PrintData printData;
|
||||
nsresult rv = printingParent->SerializeAndEnsureRemotePrintJob(
|
||||
aPrintSettings, aProgressListener, nullptr, &printData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool success = mRemoteBrowser->SendPrint(printData);
|
||||
return success ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mDocShell) {
|
||||
nsCOMPtr<nsIContentViewer> viewer;
|
||||
mDocShell->GetContentViewer(getter_AddRefs(viewer));
|
||||
if (!viewer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint = do_QueryInterface(viewer);
|
||||
if (!webBrowserPrint) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return webBrowserPrint->Print(aPrintSettings, aProgressListener);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [infallible] */ NS_IMETHODIMP
|
||||
nsFrameLoader::SetVisible(bool aVisible)
|
||||
{
|
||||
|
@ -16,6 +16,8 @@ interface nsIVariant;
|
||||
interface nsIDOMElement;
|
||||
interface nsITabParent;
|
||||
interface nsILoadContext;
|
||||
interface nsIPrintSettings;
|
||||
interface nsIWebProgressListener;
|
||||
|
||||
[scriptable, builtinclass, uuid(1645af04-1bc7-4363-8f2c-eb9679220ab1)]
|
||||
interface nsIFrameLoader : nsISupports
|
||||
@ -139,6 +141,16 @@ interface nsIFrameLoader : nsISupports
|
||||
void requestNotifyLayerTreeReady();
|
||||
void requestNotifyLayerTreeCleared();
|
||||
|
||||
/**
|
||||
* Print the current document.
|
||||
*
|
||||
* @param aPrintSettings optional print settings to use; printSilent can be
|
||||
* set to prevent prompting.
|
||||
* @param aProgressListener optional print progress listener.
|
||||
*/
|
||||
void print(in nsIPrintSettings aPrintSettings,
|
||||
in nsIWebProgressListener aProgressListener);
|
||||
|
||||
/**
|
||||
* The default event mode automatically forwards the events
|
||||
* handled in EventStateManager::HandleCrossProcessEvent to
|
||||
|
@ -3846,6 +3846,17 @@ ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
already_AddRefed<embedding::PrintingParent>
|
||||
ContentParent::GetPrintingParent()
|
||||
{
|
||||
MOZ_ASSERT(mPrintingParent);
|
||||
|
||||
RefPtr<embedding::PrintingParent> printingParent = mPrintingParent;
|
||||
return printingParent.forget();
|
||||
}
|
||||
#endif
|
||||
|
||||
PSendStreamParent*
|
||||
ContentParent::AllocPSendStreamParent()
|
||||
{
|
||||
|
@ -386,6 +386,13 @@ public:
|
||||
|
||||
virtual bool DeallocPPrintingParent(PPrintingParent* aActor) override;
|
||||
|
||||
#if defined(NS_PRINTING)
|
||||
/**
|
||||
* @return the PrintingParent for this ContentParent.
|
||||
*/
|
||||
already_AddRefed<embedding::PrintingParent> GetPrintingParent();
|
||||
#endif
|
||||
|
||||
virtual PSendStreamParent* AllocPSendStreamParent() override;
|
||||
virtual bool DeallocPSendStreamParent(PSendStreamParent* aActor) override;
|
||||
|
||||
|
@ -15,10 +15,12 @@ include protocol PFilePicker;
|
||||
include protocol PIndexedDBPermissionRequest;
|
||||
include protocol PRenderFrame;
|
||||
include protocol PPluginWidget;
|
||||
include protocol PRemotePrintJob;
|
||||
include DOMTypes;
|
||||
include JavaScriptTypes;
|
||||
include URIParams;
|
||||
include BrowserConfiguration;
|
||||
include PPrintingTypes;
|
||||
include PTabContext;
|
||||
|
||||
|
||||
@ -782,6 +784,13 @@ child:
|
||||
async HandledWindowedPluginKeyEvent(NativeEventData aKeyEventData,
|
||||
bool aIsConsumed);
|
||||
|
||||
/**
|
||||
* Tell the child to print the current page with the given settings.
|
||||
*
|
||||
* @param aPrintData the serialized settings to print with
|
||||
*/
|
||||
async Print(PrintData aPrintData);
|
||||
|
||||
/*
|
||||
* FIXME: write protocol!
|
||||
|
||||
|
@ -112,6 +112,13 @@
|
||||
#include "nsDeviceContext.h"
|
||||
#include "FrameLayerBuilder.h"
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
#include "nsIPrintSession.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#endif
|
||||
|
||||
#define BROWSER_ELEMENT_CHILD_SCRIPT \
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
|
||||
|
||||
@ -2435,6 +2442,45 @@ TabChild::RecvSetUseGlobalHistory(const bool& aUse)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvPrint(const PrintData& aPrintData)
|
||||
{
|
||||
#ifdef NS_PRINTING
|
||||
nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint = do_GetInterface(mWebNav);
|
||||
if (NS_WARN_IF(!webBrowserPrint)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1");
|
||||
if (NS_WARN_IF(!printSettingsSvc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> printSettings;
|
||||
nsresult rv =
|
||||
printSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSession> printSession =
|
||||
do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
printSettings->SetPrintSession(printSession);
|
||||
printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings);
|
||||
rv = webBrowserPrint->Print(printSettings, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvDestroy()
|
||||
{
|
||||
|
@ -580,6 +580,8 @@ public:
|
||||
const mozilla::NativeEventData& aKeyEventData,
|
||||
const bool& aIsConsumed) override;
|
||||
|
||||
virtual bool RecvPrint(const PrintData& aPrintData) override;
|
||||
|
||||
/**
|
||||
* Native widget remoting protocol for use with windowed plugins with e10s.
|
||||
*/
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIPrintOptions.h"
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@ -99,26 +98,22 @@ PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
|
||||
// nsIWebBrowserPrint to keep the dialogs happy.
|
||||
nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(aData);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> settings;
|
||||
rv = printSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
nsresult rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = printSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
rv = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = pps->ShowPrintDialog(parentWin, wbp, settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// And send it back.
|
||||
rv = printSettingsSvc->SerializeToPrintData(settings, nullptr, aResult);
|
||||
|
||||
PRemotePrintJobParent* remotePrintJob = new RemotePrintJobParent(settings);
|
||||
aResult->remotePrintJobParent() = SendPRemotePrintJobConstructor(remotePrintJob);
|
||||
// Serialize back to aResult. Use the existing RemotePrintJob if we have one
|
||||
// otherwise SerializeAndEnsureRemotePrintJob() will create a new one.
|
||||
RemotePrintJobParent* remotePrintJob =
|
||||
static_cast<RemotePrintJobParent*>(aData.remotePrintJobParent());
|
||||
rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
|
||||
aResult);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -149,18 +144,14 @@ PrintingParent::RecvSavePrintSettings(const PrintData& aData,
|
||||
const uint32_t& aFlags,
|
||||
nsresult* aResult)
|
||||
{
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", aResult);
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> settings;
|
||||
*aResult = printSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
*aResult = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
*aResult = printSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
*aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
*aResult = printSettingsSvc->SavePrintSettingsToPrefs(settings,
|
||||
*aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs(settings,
|
||||
aUsePrinterNamePrefix,
|
||||
aFlags);
|
||||
|
||||
@ -249,14 +240,58 @@ PrintingParent::DOMWindowFromBrowserParent(PBrowserParent* parent)
|
||||
return parentWin;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PrintingParent::SerializeAndEnsureRemotePrintJob(
|
||||
nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener,
|
||||
layout::RemotePrintJobParent* aRemotePrintJob, PrintData* aPrintData)
|
||||
{
|
||||
MOZ_ASSERT(aPrintData);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintSettings> printSettings;
|
||||
if (aPrintSettings) {
|
||||
printSettings = aPrintSettings;
|
||||
} else {
|
||||
rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
rv = mPrintSettingsSvc->SerializeToPrintData(aPrintSettings, nullptr,
|
||||
aPrintData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
RemotePrintJobParent* remotePrintJob;
|
||||
if (aRemotePrintJob) {
|
||||
remotePrintJob = aRemotePrintJob;
|
||||
aPrintData->remotePrintJobParent() = remotePrintJob;
|
||||
} else {
|
||||
remotePrintJob = new RemotePrintJobParent(aPrintSettings);
|
||||
aPrintData->remotePrintJobParent() =
|
||||
SendPRemotePrintJobConstructor(remotePrintJob);
|
||||
}
|
||||
if (aListener) {
|
||||
remotePrintJob->RegisterListener(aListener);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PrintingParent::PrintingParent()
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintingParent);
|
||||
MOZ_COUNT_CTOR(PrintingParent);
|
||||
|
||||
mPrintSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1");
|
||||
MOZ_ASSERT(mPrintSettingsSvc);
|
||||
}
|
||||
|
||||
PrintingParent::~PrintingParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PrintingParent);
|
||||
MOZ_COUNT_DTOR(PrintingParent);
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
#include "mozilla/embedding/PPrintingParent.h"
|
||||
|
||||
class nsIPrintSettingsService;
|
||||
class nsIWebProgressListener;
|
||||
class nsPIDOMWindowOuter;
|
||||
class PPrintProgressDialogParent;
|
||||
class PPrintSettingsDialogParent;
|
||||
@ -17,6 +19,7 @@ class PPrintSettingsDialogParent;
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
class PRemotePrintJobParent;
|
||||
class RemotePrintJobParent;
|
||||
}
|
||||
|
||||
namespace embedding {
|
||||
@ -67,6 +70,25 @@ public:
|
||||
|
||||
MOZ_IMPLICIT PrintingParent();
|
||||
|
||||
/**
|
||||
* Serialize nsIPrintSettings to PrintData ready for sending to a child
|
||||
* process. A RemotePrintJob will be created and added to the PrintData.
|
||||
* An optional progress listener can be given, which will be registered
|
||||
* with the RemotePrintJob, so that progress can be tracked in the parent.
|
||||
*
|
||||
* @param aPrintSettings optional print settings to serialize, otherwise a
|
||||
* default print settings will be used.
|
||||
* @param aProgressListener optional print progress listener.
|
||||
* @param aRemotePrintJob optional remote print job, so that an existing
|
||||
* one can be used.
|
||||
* @param aPrintData PrintData to populate.
|
||||
*/
|
||||
nsresult
|
||||
SerializeAndEnsureRemotePrintJob(nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aListener,
|
||||
layout::RemotePrintJobParent* aRemotePrintJob,
|
||||
PrintData* aPrintData);
|
||||
|
||||
private:
|
||||
virtual ~PrintingParent();
|
||||
|
||||
@ -77,6 +99,8 @@ private:
|
||||
ShowPrintDialog(PBrowserParent* parent,
|
||||
const PrintData& data,
|
||||
PrintData* result);
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsService> mPrintSettingsSvc;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
|
@ -475,14 +475,29 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
|
||||
}
|
||||
|
||||
// Create a print session and let the print settings know about it.
|
||||
// Don't overwrite an existing print session.
|
||||
// The print settings hold an nsWeakPtr to the session so it does not
|
||||
// need to be cleared from the settings at the end of the job.
|
||||
// XXX What lifetime does the printSession need to have?
|
||||
nsCOMPtr<nsIPrintSession> printSession;
|
||||
bool remotePrintJobListening = false;
|
||||
if (!aIsPrintPreview) {
|
||||
printSession = do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mPrt->mPrintSettings->SetPrintSession(printSession);
|
||||
rv = mPrt->mPrintSettings->GetPrintSession(getter_AddRefs(printSession));
|
||||
if (NS_FAILED(rv) || !printSession) {
|
||||
printSession = do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mPrt->mPrintSettings->SetPrintSession(printSession);
|
||||
} else {
|
||||
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
||||
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
if (NS_SUCCEEDED(rv) && remotePrintJob) {
|
||||
// If we have a RemotePrintJob add it to the print progress listeners,
|
||||
// so it can forward to the parent.
|
||||
mPrt->mPrintProgressListeners.AppendElement(remotePrintJob);
|
||||
remotePrintJobListening = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (aWebProgressListener != nullptr) {
|
||||
@ -613,11 +628,15 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
|
||||
// The user might have changed shrink-to-fit in the print dialog, so update our copy of its state
|
||||
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
|
||||
|
||||
// Add thee RemotePrintJob as a listener if there is one.
|
||||
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
||||
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
if (NS_SUCCEEDED(rv) && remotePrintJob) {
|
||||
mPrt->mPrintProgressListeners.AppendElement(remotePrintJob);
|
||||
// If we haven't already added the RemotePrintJob as a listener,
|
||||
// add it now if there is one.
|
||||
if (!remotePrintJobListening) {
|
||||
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
||||
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
if (NS_SUCCEEDED(rv) && remotePrintJob) {
|
||||
mPrt->mPrintProgressListeners.AppendElement(remotePrintJob);
|
||||
remotePrintJobListening = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
|
@ -1326,6 +1326,22 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="print">
|
||||
<parameter name="aPrintSettings"/>
|
||||
<parameter name="aPrintProgressListener"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var owner = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
|
||||
if (!owner.frameLoader) {
|
||||
throw Components.Exception("No frame loader.",
|
||||
Components.results.NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
owner.frameLoader.print(aPrintSettings, aPrintProgressListener);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!-- This will go away if the binding has been removed for some reason. -->
|
||||
<field name="_alive">true</field>
|
||||
</implementation>
|
||||
|
@ -105,6 +105,16 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
nsIWebBrowserPrint* aWBP,
|
||||
PrintData* data)
|
||||
{
|
||||
nsCOMPtr<nsIPrintSession> session;
|
||||
nsresult rv = aSettings->GetPrintSession(getter_AddRefs(session));
|
||||
if (NS_SUCCEEDED(rv) && session) {
|
||||
RefPtr<RemotePrintJobChild> remotePrintJob;
|
||||
rv = session->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
data->remotePrintJobChild() = remotePrintJob;
|
||||
}
|
||||
}
|
||||
|
||||
aSettings->GetStartPageRange(&data->startPageRange());
|
||||
aSettings->GetEndPageRange(&data->endPageRange());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user