diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /toolkit/components/printingui | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/printingui')
24 files changed, 2055 insertions, 0 deletions
diff --git a/toolkit/components/printingui/ipc/PPrintProgressDialog.ipdl b/toolkit/components/printingui/ipc/PPrintProgressDialog.ipdl new file mode 100644 index 0000000000..433c062158 --- /dev/null +++ b/toolkit/components/printingui/ipc/PPrintProgressDialog.ipdl @@ -0,0 +1,36 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* 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 protocol PPrinting; + +namespace mozilla { +namespace embedding { + +protocol PPrintProgressDialog +{ + manager PPrinting; + +parent: + async StateChange(long stateFlags, + nsresult status); + + async ProgressChange(long curSelfProgress, + long maxSelfProgress, + long curTotalProgress, + long maxTotalProgress); + + async DocTitleChange(nsString newTitle); + + async DocURLChange(nsString newURL); + + async __delete__(); + +child: + async DialogOpened(); + async CancelledCurrentJob(); +}; + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PPrintSettingsDialog.ipdl b/toolkit/components/printingui/ipc/PPrintSettingsDialog.ipdl new file mode 100644 index 0000000000..3e436892ed --- /dev/null +++ b/toolkit/components/printingui/ipc/PPrintSettingsDialog.ipdl @@ -0,0 +1,29 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* 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 PPrintingTypes; +include protocol PPrinting; +include protocol PRemotePrintJob; + +namespace mozilla { +namespace embedding { + +// A PrintData for success, a failure nsresult for failure. +union PrintDataOrNSResult +{ + PrintData; + nsresult; +}; + +protocol PPrintSettingsDialog +{ + manager PPrinting; + +child: + async __delete__(PrintDataOrNSResult result); +}; + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PPrinting.ipdl b/toolkit/components/printingui/ipc/PPrinting.ipdl new file mode 100644 index 0000000000..5adf0e930b --- /dev/null +++ b/toolkit/components/printingui/ipc/PPrinting.ipdl @@ -0,0 +1,46 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* 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 PPrintingTypes; +include protocol PContent; +include protocol PBrowser; +include protocol PPrintProgressDialog; +include protocol PPrintSettingsDialog; +include protocol PRemotePrintJob; + +namespace mozilla { +namespace embedding { + +sync protocol PPrinting +{ + manager PContent; + manages PPrintProgressDialog; + manages PPrintSettingsDialog; + manages PRemotePrintJob; + +parent: + async ShowProgress(PBrowser browser, + PPrintProgressDialog printProgressDialog, + nullable PRemotePrintJob remotePrintJob, + bool isForPrinting); + + async ShowPrintDialog(PPrintSettingsDialog dialog, + nullable PBrowser browser, + PrintData settings); + + async PPrintProgressDialog(); + async PPrintSettingsDialog(); + + sync SavePrintSettings(PrintData settings, bool usePrinterNamePrefix, + uint32_t flags) + returns(nsresult rv); + +child: + async PRemotePrintJob(); + async __delete__(); +}; + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PPrintingTypes.ipdlh b/toolkit/components/printingui/ipc/PPrintingTypes.ipdlh new file mode 100644 index 0000000000..2e33907206 --- /dev/null +++ b/toolkit/components/printingui/ipc/PPrintingTypes.ipdlh @@ -0,0 +1,94 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* 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 protocol PRemotePrintJob; + +namespace mozilla { +namespace embedding { + +struct CStringKeyValue { + nsCString key; + nsCString value; +}; + +struct PrintData { + nullable PRemotePrintJob remotePrintJob; + double edgeTop; + double edgeLeft; + double edgeBottom; + double edgeRight; + double marginTop; + double marginLeft; + double marginBottom; + double marginRight; + double unwriteableMarginTop; + double unwriteableMarginLeft; + double unwriteableMarginBottom; + double unwriteableMarginRight; + double scaling; + bool printBGColors; + bool printBGImages; + bool honorPageRuleMargins; + bool showMarginGuides; + bool isPrintSelectionRBEnabled; + bool printSelectionOnly; + int32_t[] pageRanges; + nsString title; + nsString docURL; + nsString headerStrLeft; + nsString headerStrCenter; + nsString headerStrRight; + nsString footerStrLeft; + nsString footerStrCenter; + nsString footerStrRight; + + bool isCancelled; + bool printSilent; + bool shrinkToFit; + bool showPrintProgress; + + nsString paperId; + double paperWidth; + double paperHeight; + short paperSizeUnit; + bool printReversed; + bool printInColor; + int32_t orientation; + int32_t numCopies; + int32_t numPagesPerSheet; + nsString printerName; + bool printToFile; + nsString toFileName; + short outputFormat; + int32_t printPageDelay; + int32_t resolution; + int32_t duplex; + bool isInitializedFromPrinter; + bool isInitializedFromPrefs; + + /* Windows-specific things */ + nsString driverName; + nsString deviceName; + uint8_t[] devModeData; + + /** + * GTK-specific things. Some of these might look like dupes of the + * information we're already passing, but the generalized settings that + * we hold in nsIPrintSettings don't map perfectly to GTK's GtkPrintSettings, + * so there are some nuances. GtkPrintSettings, for example, stores both an + * internal name for paper size, as well as the display name. + */ + CStringKeyValue[] GTKPrintSettings; + + /* + * macOS-specific things: + * What the Cocoa print system is supposed to do with the job. + */ + nsString disposition; + uint16_t destination; +}; + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogChild.cpp b/toolkit/components/printingui/ipc/PrintProgressDialogChild.cpp new file mode 100644 index 0000000000..c3b5adfb22 --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintProgressDialogChild.cpp @@ -0,0 +1,128 @@ +/* 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 "mozilla/Unused.h" +#include "nsIObserver.h" +#include "nsIPrintProgressParams.h" +#include "PrintProgressDialogChild.h" + +class nsIWebProgress; +class nsIRequest; + +using mozilla::Unused; + +namespace mozilla { +namespace embedding { + +NS_IMPL_ISUPPORTS(PrintProgressDialogChild, nsIWebProgressListener, + nsIPrintProgressParams) + +PrintProgressDialogChild::PrintProgressDialogChild( + nsIObserver* aOpenObserver, nsIPrintSettings* aPrintSettings) + : mOpenObserver(aOpenObserver), mPrintSettings(aPrintSettings) {} + +PrintProgressDialogChild::~PrintProgressDialogChild() { + // When the printing engine stops supplying information about printing + // progress, it'll drop references to us and destroy us. We need to signal + // the parent to decrement its refcount, as well as prevent it from attempting + // to contact us further. + Unused << Send__delete__(this); +} + +mozilla::ipc::IPCResult PrintProgressDialogChild::RecvDialogOpened() { + // nsPrintJob's observer, which we're reporting to here, doesn't care + // what gets passed as the subject, topic or data, so we'll just send + // nullptrs. + mOpenObserver->Observe(nullptr, nullptr, nullptr); + return IPC_OK(); +} + +mozilla::ipc::IPCResult PrintProgressDialogChild::RecvCancelledCurrentJob() { + if (mPrintSettings) { + mPrintSettings->SetIsCancelled(true); + } + return IPC_OK(); +} + +// nsIWebProgressListener + +NS_IMETHODIMP +PrintProgressDialogChild::OnStateChange(nsIWebProgress* aProgress, + nsIRequest* aRequest, + uint32_t aStateFlags, + nsresult aStatus) { + Unused << SendStateChange(aStateFlags, aStatus); + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::OnProgressChange(nsIWebProgress* aProgress, + nsIRequest* aRequest, + int32_t aCurSelfProgress, + int32_t aMaxSelfProgress, + int32_t aCurTotalProgress, + int32_t aMaxTotalProgress) { + Unused << SendProgressChange(aCurSelfProgress, aMaxSelfProgress, + aCurTotalProgress, aMaxTotalProgress); + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::OnLocationChange(nsIWebProgress* aProgress, + nsIRequest* aRequest, nsIURI* aURI, + uint32_t aFlags) { + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::OnStatusChange(nsIWebProgress* aProgress, + nsIRequest* aRequest, nsresult aStatus, + const char16_t* aMessage) { + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::OnSecurityChange(nsIWebProgress* aProgress, + nsIRequest* aRequest, + uint32_t aState) { + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::OnContentBlockingEvent(nsIWebProgress* aProgress, + nsIRequest* aRequest, + uint32_t aEvent) { + return NS_OK; +} + +// nsIPrintProgressParams + +NS_IMETHODIMP +PrintProgressDialogChild::GetDocTitle(nsAString& aDocTitle) { + aDocTitle = mDocTitle; + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::SetDocTitle(const nsAString& aDocTitle) { + mDocTitle = aDocTitle; + Unused << SendDocTitleChange(PromiseFlatString(aDocTitle)); + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::GetDocURL(nsAString& aDocURL) { + aDocURL = mDocURL; + return NS_OK; +} + +NS_IMETHODIMP +PrintProgressDialogChild::SetDocURL(const nsAString& aDocURL) { + mDocURL = aDocURL; + Unused << SendDocURLChange(PromiseFlatString(aDocURL)); + return NS_OK; +} + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogChild.h b/toolkit/components/printingui/ipc/PrintProgressDialogChild.h new file mode 100644 index 0000000000..74899c07f9 --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintProgressDialogChild.h @@ -0,0 +1,43 @@ +/* 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/. */ + +#ifndef mozilla_embedding_PrintProgressDialogChild_h +#define mozilla_embedding_PrintProgressDialogChild_h + +#include "mozilla/embedding/PPrintProgressDialogChild.h" +#include "nsIPrintSettings.h" +#include "nsIWebProgressListener.h" + +class nsIObserver; + +namespace mozilla { +namespace embedding { + +class PrintProgressDialogChild final : public PPrintProgressDialogChild, + public nsIWebProgressListener, + public nsIPrintProgressParams { + NS_DECL_ISUPPORTS + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSIPRINTPROGRESSPARAMS + + public: + MOZ_IMPLICIT PrintProgressDialogChild(nsIObserver* aOpenObserver, + nsIPrintSettings* aPrintSettings); + + virtual mozilla::ipc::IPCResult RecvDialogOpened() override; + + virtual mozilla::ipc::IPCResult RecvCancelledCurrentJob() override; + + private: + virtual ~PrintProgressDialogChild(); + nsCOMPtr<nsIObserver> mOpenObserver; + nsString mDocTitle; + nsString mDocURL; + nsCOMPtr<nsIPrintSettings> mPrintSettings; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp b/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp new file mode 100644 index 0000000000..fcc463808b --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp @@ -0,0 +1,111 @@ +/* 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 "mozilla/Unused.h" +#include "nsIWebProgressListener.h" +#include "PrintProgressDialogParent.h" + +using mozilla::Unused; + +namespace mozilla { +namespace embedding { + +NS_IMPL_ISUPPORTS(PrintProgressDialogParent, nsIObserver) + +PrintProgressDialogParent::PrintProgressDialogParent() : mActive(true) {} + +PrintProgressDialogParent::~PrintProgressDialogParent() = default; + +void PrintProgressDialogParent::SetWebProgressListener( + nsIWebProgressListener* aListener) { + mWebProgressListener = aListener; +} + +void PrintProgressDialogParent::SetPrintProgressParams( + nsIPrintProgressParams* aParams) { + mPrintProgressParams = aParams; +} + +mozilla::ipc::IPCResult PrintProgressDialogParent::RecvStateChange( + const long& stateFlags, const nsresult& status) { + if (mWebProgressListener) { + mWebProgressListener->OnStateChange(nullptr, nullptr, stateFlags, status); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult PrintProgressDialogParent::RecvProgressChange( + const long& curSelfProgress, const long& maxSelfProgress, + const long& curTotalProgress, const long& maxTotalProgress) { + if (mWebProgressListener) { + mWebProgressListener->OnProgressChange(nullptr, nullptr, curSelfProgress, + maxSelfProgress, curTotalProgress, + maxTotalProgress); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult PrintProgressDialogParent::RecvDocTitleChange( + const nsString& newTitle) { + if (mPrintProgressParams) { + mPrintProgressParams->SetDocTitle(newTitle); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult PrintProgressDialogParent::RecvDocURLChange( + const nsString& newURL) { + if (mPrintProgressParams) { + mPrintProgressParams->SetDocURL(newURL); + } + return IPC_OK(); +} + +void PrintProgressDialogParent::ActorDestroy(ActorDestroyReason aWhy) { + // If IPC actor is destroyed, we can't send to child via IPC. + mActive = false; +} + +mozilla::ipc::IPCResult PrintProgressDialogParent::Recv__delete__() { + // The child has requested that we tear down the connection, so we set a + // member to make sure we don't try to contact it after the fact. + mActive = false; + return IPC_OK(); +} + +// nsIObserver +NS_IMETHODIMP +PrintProgressDialogParent::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + if (mActive) { + if (aTopic) { + if (!strcmp(aTopic, "cancelled")) { + Unused << SendCancelledCurrentJob(); + if (!mDialogOpenedSent) { + // We haven't already called SendDialogOpened, so call it now or it + // might never get sent and block the child from new printing + // requests. Also set mActive to false because we don't want to send + // it twice and our PrintProgressDialogChild will get deleted anyway. + Unused << SendDialogOpened(); + mActive = false; + } + } else if (!strcmp(aTopic, "completed")) { + // Once printing is complete don't send any messages to the child. + mActive = false; + } + } else { + Unused << SendDialogOpened(); + mDialogOpenedSent = true; + } + } else { + NS_WARNING( + "The print progress dialog finished opening, but communications " + "with the child have been closed."); + } + + return NS_OK; +} + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogParent.h b/toolkit/components/printingui/ipc/PrintProgressDialogParent.h new file mode 100644 index 0000000000..5995446aaf --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintProgressDialogParent.h @@ -0,0 +1,57 @@ +/* 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/. */ + +#ifndef mozilla_embedding_PrintProgressDialogParent_h +#define mozilla_embedding_PrintProgressDialogParent_h + +#include "mozilla/embedding/PPrintProgressDialogParent.h" +#include "nsIObserver.h" + +class nsIPrintProgressParams; +class nsIWebProgressListener; + +namespace mozilla { +namespace embedding { +class PrintProgressDialogParent final : public PPrintProgressDialogParent, + public nsIObserver { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + MOZ_IMPLICIT PrintProgressDialogParent(); + + void SetWebProgressListener(nsIWebProgressListener* aListener); + + void SetPrintProgressParams(nsIPrintProgressParams* aParams); + + virtual mozilla::ipc::IPCResult RecvStateChange( + const long& stateFlags, const nsresult& status) override; + + virtual mozilla::ipc::IPCResult RecvProgressChange( + const long& curSelfProgress, const long& maxSelfProgress, + const long& curTotalProgress, const long& maxTotalProgress) override; + + virtual mozilla::ipc::IPCResult RecvDocTitleChange( + const nsString& newTitle) override; + + virtual mozilla::ipc::IPCResult RecvDocURLChange( + const nsString& newURL) override; + + virtual void ActorDestroy(ActorDestroyReason aWhy) override; + + virtual mozilla::ipc::IPCResult Recv__delete__() override; + + private: + virtual ~PrintProgressDialogParent(); + + nsCOMPtr<nsIWebProgressListener> mWebProgressListener; + nsCOMPtr<nsIPrintProgressParams> mPrintProgressParams; + bool mActive; + bool mDialogOpenedSent = false; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogChild.cpp b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.cpp new file mode 100644 index 0000000000..b6b1578950 --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.cpp @@ -0,0 +1,34 @@ +/* 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 "PrintSettingsDialogChild.h" + +using mozilla::Unused; + +namespace mozilla { +namespace embedding { + +PrintSettingsDialogChild::PrintSettingsDialogChild() : mReturned(false) { + MOZ_COUNT_CTOR(PrintSettingsDialogChild); +} + +PrintSettingsDialogChild::~PrintSettingsDialogChild() { + MOZ_COUNT_DTOR(PrintSettingsDialogChild); +} + +mozilla::ipc::IPCResult PrintSettingsDialogChild::Recv__delete__( + const PrintDataOrNSResult& aData) { + if (aData.type() == PrintDataOrNSResult::Tnsresult) { + mResult = aData.get_nsresult(); + MOZ_ASSERT(NS_FAILED(mResult), "expected a failure result"); + } else { + mResult = NS_OK; + mData = aData.get_PrintData(); + } + mReturned = true; + return IPC_OK(); +} + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogChild.h b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.h new file mode 100644 index 0000000000..9666117eb1 --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.h @@ -0,0 +1,35 @@ +/* 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/. */ + +#ifndef mozilla_embedding_PrintSettingsDialogChild_h +#define mozilla_embedding_PrintSettingsDialogChild_h + +#include "mozilla/embedding/PPrintSettingsDialogChild.h" +namespace mozilla { +namespace embedding { + +class PrintSettingsDialogChild final : public PPrintSettingsDialogChild { + NS_INLINE_DECL_REFCOUNTING(PrintSettingsDialogChild) + + public: + MOZ_IMPLICIT PrintSettingsDialogChild(); + + virtual mozilla::ipc::IPCResult Recv__delete__( + const PrintDataOrNSResult& aData) override; + + bool returned() { return mReturned; }; + nsresult result() { return mResult; }; + PrintData data() { return mData; }; + + private: + virtual ~PrintSettingsDialogChild(); + bool mReturned; + nsresult mResult; + PrintData mData; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogParent.cpp b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.cpp new file mode 100644 index 0000000000..ae784fef12 --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.cpp @@ -0,0 +1,22 @@ +/* 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 "PrintSettingsDialogParent.h" + +// C++ file contents +namespace mozilla { +namespace embedding { + +PrintSettingsDialogParent::PrintSettingsDialogParent() { + MOZ_COUNT_CTOR(PrintSettingsDialogParent); +} + +PrintSettingsDialogParent::~PrintSettingsDialogParent() { + MOZ_COUNT_DTOR(PrintSettingsDialogParent); +} + +void PrintSettingsDialogParent::ActorDestroy(ActorDestroyReason aWhy) {} + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogParent.h b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.h new file mode 100644 index 0000000000..8d4fa87067 --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.h @@ -0,0 +1,27 @@ +/* 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/. */ + +#ifndef mozilla_embedding_PrintSettingsDialogParent_h +#define mozilla_embedding_PrintSettingsDialogParent_h + +#include "mozilla/embedding/PPrintSettingsDialogParent.h" + +// Header file contents +namespace mozilla { +namespace embedding { + +class PrintSettingsDialogParent final : public PPrintSettingsDialogParent { + public: + virtual void ActorDestroy(ActorDestroyReason aWhy) override; + + MOZ_IMPLICIT PrintSettingsDialogParent(); + + private: + virtual ~PrintSettingsDialogParent(); +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/toolkit/components/printingui/ipc/PrintingParent.cpp b/toolkit/components/printingui/ipc/PrintingParent.cpp new file mode 100644 index 0000000000..69a7e4006f --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintingParent.cpp @@ -0,0 +1,307 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "mozilla/dom/Element.h" +#include "mozilla/dom/BrowserParent.h" +#include "mozilla/Preferences.h" +#include "mozilla/Unused.h" +#include "nsIContent.h" +#include "mozilla/dom/Document.h" +#include "nsIPrintingPromptService.h" +#include "nsIPrintSettingsService.h" +#include "nsServiceManagerUtils.h" +#include "nsIWebProgressListener.h" +#include "PrintingParent.h" +#include "PrintProgressDialogParent.h" +#include "PrintSettingsDialogParent.h" +#include "mozilla/layout/RemotePrintJobParent.h" +#include "mozilla/StaticPrefs_print.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::layout; + +namespace mozilla { +namespace embedding { +mozilla::ipc::IPCResult PrintingParent::RecvShowProgress( + PBrowserParent* parent, PPrintProgressDialogParent* printProgressDialog, + PRemotePrintJobParent* remotePrintJob, const bool& isForPrinting) { + bool notifyOnOpen = false; + + nsCOMPtr<nsPIDOMWindowOuter> parentWin = DOMWindowFromBrowserParent(parent); + nsCOMPtr<nsIPrintingPromptService> pps( + do_GetService("@mozilla.org/embedcomp/printingprompt-service;1")); + + PrintProgressDialogParent* dialogParent = + static_cast<PrintProgressDialogParent*>(printProgressDialog); + nsCOMPtr<nsIObserver> observer = dialogParent; + + nsCOMPtr<nsIWebProgressListener> printProgressListener; + nsCOMPtr<nsIPrintProgressParams> printProgressParams; + + nsresult rv = NS_ERROR_INVALID_ARG; + if (parentWin && pps) { + rv = pps->ShowPrintProgressDialog( + parentWin, nullptr, observer, isForPrinting, + getter_AddRefs(printProgressListener), + getter_AddRefs(printProgressParams), ¬ifyOnOpen); + } + + if (NS_SUCCEEDED(rv)) { + if (remotePrintJob) { + // If we have a RemotePrintJob use that as a more general forwarder for + // print progress listeners. + static_cast<RemotePrintJobParent*>(remotePrintJob) + ->RegisterListener(printProgressListener); + } else { + dialogParent->SetWebProgressListener(printProgressListener); + } + + dialogParent->SetPrintProgressParams(printProgressParams); + } + + // NOTE: If we aren't going to observe an event on our observer, we need to + // fake one. This takes the form of sending the SendDialogOpened message. This + // is safe because the child process proxy will always return `true` for + // notifyOnOpen, as the request will always be async when performed across + // process boundaries. + // + // We can pass nullptr for all of the arguments, as all consumers of this + // observer don't care about the subject, topic, or data. + // + // If notifyOnOpen is true, then the ShowProgress call will handle notifying + // our observer for us. + if (!notifyOnOpen) { + observer->Observe(nullptr, nullptr, nullptr); + } + return IPC_OK(); +} + +nsresult PrintingParent::ShowPrintDialog(PBrowserParent* aParent, + const PrintData& aData, + PrintData* aResult) { + // If aParent is null this call is just being used to get print settings from + // the printer for print preview. + bool isPrintPreview = !aParent; + nsCOMPtr<nsPIDOMWindowOuter> parentWin; + if (aParent) { + parentWin = DOMWindowFromBrowserParent(aParent); + if (!parentWin) { + return NS_ERROR_FAILURE; + } + } + + nsCOMPtr<nsIPrintingPromptService> pps( + do_GetService("@mozilla.org/embedcomp/printingprompt-service;1")); + if (!pps) { + return NS_ERROR_FAILURE; + } + + // Use the existing RemotePrintJob and its settings, if we have one, to make + // sure they stay current. + RemotePrintJobParent* remotePrintJob = + static_cast<RemotePrintJobParent*>(aData.remotePrintJobParent()); + nsCOMPtr<nsIPrintSettings> settings; + nsresult rv; + if (remotePrintJob) { + settings = remotePrintJob->GetPrintSettings(); + } else { + rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings)); + NS_ENSURE_SUCCESS(rv, rv); + } + + // We only want to use the print silently setting from the parent. + bool printSilently; + rv = settings->GetPrintSilent(&printSilently); + NS_ENSURE_SUCCESS(rv, rv); + + rv = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings); + NS_ENSURE_SUCCESS(rv, rv); + + rv = settings->SetPrintSilent(printSilently); + NS_ENSURE_SUCCESS(rv, rv); + + nsString printerName; + settings->GetPrinterName(printerName); +#ifdef MOZ_X11 + // Requesting the last-used printer name on Linux has been removed in the + // child, because it was causing a sandbox violation (see Bug 1329216). If no + // printer name is set at this point, use the print settings service to get + // the last-used printer name, unless we're printing to file. + bool printToFile = false; + MOZ_ALWAYS_SUCCEEDS(settings->GetPrintToFile(&printToFile)); + if (!printToFile && printerName.IsEmpty()) { + mPrintSettingsSvc->GetLastUsedPrinterName(printerName); + settings->SetPrinterName(printerName); + } + mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings); +#endif + + // If this is for print preview or we are printing silently then we just need + // to initialize the print settings with anything specific from the printer. + if (isPrintPreview || printSilently || + StaticPrefs::print_always_print_silent()) { + settings->SetIsInitializedFromPrinter(false); + mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings); + } else { + rv = pps->ShowPrintDialog(parentWin, settings); + NS_ENSURE_SUCCESS(rv, rv); + } + + if (isPrintPreview) { + // For print preview we don't want a RemotePrintJob just the settings. + rv = mPrintSettingsSvc->SerializeToPrintData(settings, aResult); + } else { + rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob, + aResult); + } + + return rv; +} + +mozilla::ipc::IPCResult PrintingParent::RecvShowPrintDialog( + PPrintSettingsDialogParent* aDialog, PBrowserParent* aParent, + const PrintData& aData) { + PrintData resultData; + nsresult rv = ShowPrintDialog(aParent, aData, &resultData); + + // The child has been spinning an event loop while waiting + // to hear about the print settings. We return the results + // with an async message which frees the child process from + // its nested event loop. + if (NS_FAILED(rv)) { + mozilla::Unused + << PPrintingParent::PPrintSettingsDialogParent::Send__delete__(aDialog, + rv); + } else { + mozilla::Unused + << PPrintingParent::PPrintSettingsDialogParent::Send__delete__( + aDialog, resultData); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult PrintingParent::RecvSavePrintSettings( + const PrintData& aData, const bool& aUsePrinterNamePrefix, + const uint32_t& aFlags, nsresult* aResult) { + nsCOMPtr<nsIPrintSettings> settings; + *aResult = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings)); + NS_ENSURE_SUCCESS(*aResult, IPC_OK()); + + *aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings); + NS_ENSURE_SUCCESS(*aResult, IPC_OK()); + + *aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs( + settings, aUsePrinterNamePrefix, aFlags); + + return IPC_OK(); +} + +PPrintProgressDialogParent* PrintingParent::AllocPPrintProgressDialogParent() { + PrintProgressDialogParent* actor = new PrintProgressDialogParent(); + NS_ADDREF(actor); // De-ref'd in the __delete__ handler for + // PrintProgressDialogParent. + return actor; +} + +bool PrintingParent::DeallocPPrintProgressDialogParent( + PPrintProgressDialogParent* doomed) { + // We can't just delete the PrintProgressDialogParent since somebody might + // still be holding a reference to it as nsIObserver, so just decrement the + // refcount instead. + PrintProgressDialogParent* actor = + static_cast<PrintProgressDialogParent*>(doomed); + NS_RELEASE(actor); + return true; +} + +PPrintSettingsDialogParent* PrintingParent::AllocPPrintSettingsDialogParent() { + return new PrintSettingsDialogParent(); +} + +bool PrintingParent::DeallocPPrintSettingsDialogParent( + PPrintSettingsDialogParent* aDoomed) { + delete aDoomed; + return true; +} + +void PrintingParent::ActorDestroy(ActorDestroyReason aWhy) {} + +nsPIDOMWindowOuter* PrintingParent::DOMWindowFromBrowserParent( + PBrowserParent* parent) { + if (!parent) { + return nullptr; + } + + BrowserParent* browserParent = BrowserParent::GetFrom(parent); + if (!browserParent) { + return nullptr; + } + + nsCOMPtr<Element> frameElement = browserParent->GetOwnerElement(); + if (!frameElement) { + return nullptr; + } + + nsCOMPtr<nsIContent> frame(frameElement); + if (!frame) { + return nullptr; + } + + nsCOMPtr<nsPIDOMWindowOuter> parentWin = frame->OwnerDoc()->GetWindow(); + if (!parentWin) { + return nullptr; + } + + 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(printSettings, 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() { + mPrintSettingsSvc = do_GetService("@mozilla.org/gfx/printsettings-service;1"); + MOZ_ASSERT(mPrintSettingsSvc); +} + +PrintingParent::~PrintingParent() = default; + +} // namespace embedding +} // namespace mozilla diff --git a/toolkit/components/printingui/ipc/PrintingParent.h b/toolkit/components/printingui/ipc/PrintingParent.h new file mode 100644 index 0000000000..9e4ab9ff03 --- /dev/null +++ b/toolkit/components/printingui/ipc/PrintingParent.h @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ +/* 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/. */ + +#ifndef mozilla_embedding_PrintingParent_h +#define mozilla_embedding_PrintingParent_h + +#include "mozilla/dom/PBrowserParent.h" +#include "mozilla/embedding/PPrintingParent.h" + +class nsIPrintSettingsService; +class nsIWebProgressListener; +class nsPIDOMWindowOuter; +class PPrintProgressDialogParent; +class PPrintSettingsDialogParent; + +namespace mozilla { +namespace layout { +class PRemotePrintJobParent; +class RemotePrintJobParent; +} // namespace layout + +namespace embedding { + +class PrintingParent final : public PPrintingParent { + public: + NS_INLINE_DECL_REFCOUNTING(PrintingParent) + + mozilla::ipc::IPCResult RecvShowProgress( + PBrowserParent* parent, PPrintProgressDialogParent* printProgressDialog, + PRemotePrintJobParent* remotePrintJob, const bool& isForPrinting) final; + mozilla::ipc::IPCResult RecvShowPrintDialog( + PPrintSettingsDialogParent* aDialog, PBrowserParent* aParent, + const PrintData& aData) final; + + mozilla::ipc::IPCResult RecvSavePrintSettings( + const PrintData& data, const bool& usePrinterNamePrefix, + const uint32_t& flags, nsresult* rv) final; + + PPrintProgressDialogParent* AllocPPrintProgressDialogParent() final; + + bool DeallocPPrintProgressDialogParent( + PPrintProgressDialogParent* aActor) final; + + PPrintSettingsDialogParent* AllocPPrintSettingsDialogParent() final; + + bool DeallocPPrintSettingsDialogParent( + PPrintSettingsDialogParent* aActor) final; + + void ActorDestroy(ActorDestroyReason aWhy) final; + + 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: + ~PrintingParent() final; + + nsPIDOMWindowOuter* DOMWindowFromBrowserParent(PBrowserParent* parent); + + nsresult ShowPrintDialog(PBrowserParent* parent, const PrintData& data, + PrintData* result); + + nsCOMPtr<nsIPrintSettingsService> mPrintSettingsSvc; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/toolkit/components/printingui/ipc/moz.build b/toolkit/components/printingui/ipc/moz.build new file mode 100644 index 0000000000..507bfc9d9d --- /dev/null +++ b/toolkit/components/printingui/ipc/moz.build @@ -0,0 +1,34 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +EXPORTS += [ + "nsPrintingProxy.h", +] + +EXPORTS.mozilla.embedding.printingui += [ + "PrintingParent.h", +] + +if CONFIG["NS_PRINTING"]: + UNIFIED_SOURCES += [ + "nsPrintingProxy.cpp", + "PrintingParent.cpp", + "PrintProgressDialogChild.cpp", + "PrintProgressDialogParent.cpp", + "PrintSettingsDialogChild.cpp", + "PrintSettingsDialogParent.cpp", + ] + +IPDL_SOURCES += [ + "PPrinting.ipdl", + "PPrintingTypes.ipdlh", + "PPrintProgressDialog.ipdl", + "PPrintSettingsDialog.ipdl", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul" diff --git a/toolkit/components/printingui/ipc/nsPrintingProxy.cpp b/toolkit/components/printingui/ipc/nsPrintingProxy.cpp new file mode 100644 index 0000000000..fdb1a9725a --- /dev/null +++ b/toolkit/components/printingui/ipc/nsPrintingProxy.cpp @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/BrowserChild.h" +#include "mozilla/layout/RemotePrintJobChild.h" +#include "mozilla/SpinEventLoopUntil.h" +#include "mozilla/Unused.h" +#include "nsIDocShell.h" +#include "nsIPrintingPromptService.h" +#include "nsIPrintSession.h" +#include "nsPIDOMWindow.h" +#include "nsPrintSettingsService.h" +#include "nsServiceManagerUtils.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() = default; + +nsPrintingProxy::~nsPrintingProxy() = default; + +/* 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, + nsIPrintSettings* printSettings) { + 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. + BrowserChild* pBrowser = nullptr; + if (parent) { + // Get the BrowserChild 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<nsIBrowserChild> tabchild = docShell->GetBrowserChild(); + NS_ENSURE_STATE(tabchild); + + pBrowser = static_cast<BrowserChild*>(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, &inSettings); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIPrintSession> session; + rv = printSettings->GetPrintSession(getter_AddRefs(session)); + if (NS_SUCCEEDED(rv) && session) { + inSettings.remotePrintJobChild() = session->GetRemotePrintJob(); + } + + // 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::ShowPrintProgressDialog( + mozIDOMWindowProxy* parent, + 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 BrowserChild 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<nsIBrowserChild> tabchild = docShell->GetBrowserChild(); + BrowserChild* pBrowser = static_cast<BrowserChild*>(tabchild.get()); + + RefPtr<PrintProgressDialogChild> dialogChild = + new PrintProgressDialogChild(openDialogObserver, printSettings); + + SendPPrintProgressDialogConstructor(dialogChild); + + // Get the RemotePrintJob if we have one available. + RefPtr<RemotePrintJobChild> remotePrintJob; + if (printSettings) { + nsCOMPtr<nsIPrintSession> printSession; + nsresult rv = printSettings->GetPrintSession(getter_AddRefs(printSession)); + if (NS_SUCCEEDED(rv) && printSession) { + remotePrintJob = printSession->GetRemotePrintJob(); + } + } + + // 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::ShowPageSetupDialog(mozIDOMWindowProxy* parent, + nsIPrintSettings* printSettings) { + 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, &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. + MOZ_ASSERT_UNREACHABLE( + "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. + MOZ_ASSERT_UNREACHABLE( + "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; +} + +already_AddRefed<PRemotePrintJobChild> +nsPrintingProxy::AllocPRemotePrintJobChild() { + RefPtr<RemotePrintJobChild> remotePrintJob = new RemotePrintJobChild(); + return remotePrintJob.forget(); +} diff --git a/toolkit/components/printingui/ipc/nsPrintingProxy.h b/toolkit/components/printingui/ipc/nsPrintingProxy.h new file mode 100644 index 0000000000..ba99b35139 --- /dev/null +++ b/toolkit/components/printingui/ipc/nsPrintingProxy.h @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef __nsPrintingProxy_h +#define __nsPrintingProxy_h + +#include "nsIPrintingPromptService.h" +#include "mozilla/embedding/PPrintingChild.h" + +namespace mozilla { +namespace layout { +class PRemotePrintJobChild; +} +} // namespace mozilla + +class nsPrintingProxy final : public nsIPrintingPromptService, + public mozilla::embedding::PPrintingChild { + friend class mozilla::embedding::PPrintingChild; + + public: + static already_AddRefed<nsPrintingProxy> GetInstance(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTINGPROMPTSERVICE + + /** + * Used to proxy nsIPrintSettings.savePrintSettingsToPrefs calls to the + * parent process. + * + * @param aFlags - kInitSave* flags from nsIPrintSettings's to specify + * which settings to save. + */ + nsresult SavePrintSettings(nsIPrintSettings* aPS, bool aUsePrinterNamePrefix, + uint32_t aFlags); + + protected: + PPrintProgressDialogChild* AllocPPrintProgressDialogChild() final; + + bool DeallocPPrintProgressDialogChild( + PPrintProgressDialogChild* aActor) final; + + PPrintSettingsDialogChild* AllocPPrintSettingsDialogChild() final; + + bool DeallocPPrintSettingsDialogChild( + PPrintSettingsDialogChild* aActor) final; + + already_AddRefed<PRemotePrintJobChild> AllocPRemotePrintJobChild() final; + + private: + nsPrintingProxy(); + + ~nsPrintingProxy() final; + + nsresult Init(); +}; + +#endif diff --git a/toolkit/components/printingui/moz.build b/toolkit/components/printingui/moz.build new file mode 100644 index 0000000000..babf5f1dec --- /dev/null +++ b/toolkit/components/printingui/moz.build @@ -0,0 +1,22 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +with Files("**"): + BUG_COMPONENT = ("Toolkit", "Printing") + +DIRS += ["ipc"] + +if CONFIG["NS_PRINTING"]: + UNIFIED_SOURCES += [ + "nsPrintingPromptService.cpp", + ] + if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows" or CONFIG["MOZ_PDF_PRINTING"]: + UNIFIED_SOURCES += [ + "nsPrintProgress.cpp", + "nsPrintProgressParams.cpp", + ] + +FINAL_LIBRARY = "xul" diff --git a/toolkit/components/printingui/nsPrintProgress.cpp b/toolkit/components/printingui/nsPrintProgress.cpp new file mode 100644 index 0000000000..a85b866600 --- /dev/null +++ b/toolkit/components/printingui/nsPrintProgress.cpp @@ -0,0 +1,265 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsPrintProgress.h" + +#include "mozilla/dom/BrowsingContext.h" +#include "nsArray.h" +#include "nsIDocShell.h" +#include "nsIDocShellTreeOwner.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIPrintSettings.h" +#include "nsIAppWindow.h" +#include "nsXPCOM.h" +#include "nsIObserver.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" +#include "nsPIDOMWindow.h" +#include "nsXULAppAPI.h" + +using mozilla::dom::BrowsingContext; + +NS_IMPL_ADDREF(nsPrintProgress) +NS_IMPL_RELEASE(nsPrintProgress) + +NS_INTERFACE_MAP_BEGIN(nsPrintProgress) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintProgress) + NS_INTERFACE_MAP_ENTRY(nsIPrintProgress) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) +NS_INTERFACE_MAP_END + +nsPrintProgress::nsPrintProgress(nsIPrintSettings* aPrintSettings) { + m_closeProgress = false; + m_processCanceled = false; + m_pendingStateFlags = -1; + m_pendingStateValue = NS_OK; + m_PrintSetting = aPrintSettings; +} + +nsPrintProgress::~nsPrintProgress() { (void)ReleaseListeners(); } + +NS_IMETHODIMP nsPrintProgress::OpenProgressDialog( + mozIDOMWindowProxy* parent, const char* dialogURL, nsISupports* parameters, + nsIObserver* openDialogObserver, bool* notifyOnOpen) { + *notifyOnOpen = true; + m_observer = openDialogObserver; + nsresult rv = NS_ERROR_FAILURE; + + if (m_dialog) return NS_ERROR_ALREADY_INITIALIZED; + + if (!dialogURL || !*dialogURL) return NS_ERROR_INVALID_ARG; + + if (parent) { + // Set up window.arguments[0]... + nsCOMPtr<nsIMutableArray> array = nsArray::Create(); + + nsCOMPtr<nsISupportsInterfacePointer> ifptr = + do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + ifptr->SetData(static_cast<nsIPrintProgress*>(this)); + ifptr->SetDataIID(&NS_GET_IID(nsIPrintProgress)); + + array->AppendElement(ifptr); + + array->AppendElement(parameters); + + // We will set the opener of the dialog to be the nsIDOMWindow for the + // browser XUL window itself, as opposed to the content. That way, the + // progress window has access to the opener. + nsCOMPtr<nsPIDOMWindowOuter> pParentWindow = + nsPIDOMWindowOuter::From(parent); + NS_ENSURE_STATE(pParentWindow); + nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell(); + NS_ENSURE_STATE(docShell); + + nsCOMPtr<nsIDocShellTreeOwner> owner; + docShell->GetTreeOwner(getter_AddRefs(owner)); + + nsCOMPtr<nsIAppWindow> ownerAppWindow = do_GetInterface(owner); + nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerAppWindow); + NS_ENSURE_STATE(ownerWindow); + + nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = + nsPIDOMWindowOuter::From(ownerWindow); + + // Open the dialog. + RefPtr<BrowsingContext> newBC; + + rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL), + u"_blank"_ns, + u"chrome,titlebar,dependent,centerscreen"_ns, + array, getter_AddRefs(newBC)); + } + + return rv; +} + +NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose) { + m_closeProgress = true; + // XXX Invalid cast of bool to nsresult (bug 778106) + return OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, + (nsresult)forceClose); +} + +NS_IMETHODIMP nsPrintProgress::GetPrompter(nsIPrompt** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = nullptr; + + if (!m_closeProgress && m_dialog) { + nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(m_dialog); + MOZ_ASSERT(window); + return window->GetPrompter(_retval); + } + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP nsPrintProgress::GetProcessCanceledByUser( + bool* aProcessCanceledByUser) { + NS_ENSURE_ARG_POINTER(aProcessCanceledByUser); + *aProcessCanceledByUser = m_processCanceled; + return NS_OK; +} +NS_IMETHODIMP nsPrintProgress::SetProcessCanceledByUser( + bool aProcessCanceledByUser) { + if (XRE_IsE10sParentProcess()) { + MOZ_ASSERT(m_observer); + m_observer->Observe(nullptr, "cancelled", nullptr); + } + if (m_PrintSetting) m_PrintSetting->SetIsCancelled(true); + m_processCanceled = aProcessCanceledByUser; + OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::RegisterListener( + nsIWebProgressListener* listener) { + if (!listener) // Nothing to do with a null listener! + return NS_OK; + + m_listenerList.AppendObject(listener); + if (m_closeProgress || m_processCanceled) + listener->OnStateChange(nullptr, nullptr, + nsIWebProgressListener::STATE_STOP, NS_OK); + else { + listener->OnStatusChange(nullptr, nullptr, NS_OK, m_pendingStatus.get()); + if (m_pendingStateFlags != -1) + listener->OnStateChange(nullptr, nullptr, m_pendingStateFlags, + m_pendingStateValue); + } + + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::UnregisterListener( + nsIWebProgressListener* listener) { + if (listener) m_listenerList.RemoveObject(listener); + + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::DoneIniting() { + if (m_observer) { + m_observer->Observe(nullptr, nullptr, nullptr); + } + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aStateFlags, + nsresult aStatus) { + if (XRE_IsE10sParentProcess() && + aStateFlags & nsIWebProgressListener::STATE_STOP) { + // If we're in an e10s parent, m_observer is a PrintProgressDialogParent, + // so we let it know that printing has completed, because it might mean that + // its PrintProgressDialogChild has already been deleted. + m_observer->Observe(nullptr, "completed", nullptr); + } + + m_pendingStateFlags = aStateFlags; + m_pendingStateValue = aStatus; + + uint32_t count = m_listenerList.Count(); + for (uint32_t i = count - 1; i < count; i--) { + nsCOMPtr<nsIWebProgressListener> progressListener = + m_listenerList.SafeObjectAt(i); + if (progressListener) + progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, + aStatus); + } + + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + int32_t aCurSelfProgress, + int32_t aMaxSelfProgress, + int32_t aCurTotalProgress, + int32_t aMaxTotalProgress) { + if (XRE_IsE10sParentProcess() && aCurSelfProgress && + aCurSelfProgress >= aMaxSelfProgress) { + // If we're in an e10s parent, m_observer is a PrintProgressDialogParent, + // so we let it know that printing has completed, because it might mean that + // its PrintProgressDialogChild has already been deleted. + m_observer->Observe(nullptr, "completed", nullptr); + } + + uint32_t count = m_listenerList.Count(); + for (uint32_t i = count - 1; i < count; i--) { + nsCOMPtr<nsIWebProgressListener> progressListener = + m_listenerList.SafeObjectAt(i); + if (progressListener) + progressListener->OnProgressChange(aWebProgress, aRequest, + aCurSelfProgress, aMaxSelfProgress, + aCurTotalProgress, aMaxTotalProgress); + } + + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::OnLocationChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsIURI* location, + uint32_t aFlags) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::OnStatusChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsresult aStatus, + const char16_t* aMessage) { + if (aMessage && *aMessage) m_pendingStatus = aMessage; + + uint32_t count = m_listenerList.Count(); + for (uint32_t i = count - 1; i < count; i--) { + nsCOMPtr<nsIWebProgressListener> progressListener = + m_listenerList.SafeObjectAt(i); + if (progressListener) + progressListener->OnStatusChange(aWebProgress, aRequest, aStatus, + aMessage); + } + + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::OnSecurityChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aState) { + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::OnContentBlockingEvent( + nsIWebProgress* aWebProgress, nsIRequest* aRequest, uint32_t aEvent) { + return NS_OK; +} + +nsresult nsPrintProgress::ReleaseListeners() { + m_listenerList.Clear(); + + return NS_OK; +} diff --git a/toolkit/components/printingui/nsPrintProgress.h b/toolkit/components/printingui/nsPrintProgress.h new file mode 100644 index 0000000000..81e89fbea1 --- /dev/null +++ b/toolkit/components/printingui/nsPrintProgress.h @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef __nsPrintProgress_h +#define __nsPrintProgress_h + +#include "nsIPrintProgress.h" + +#include "nsCOMArray.h" +#include "nsCOMPtr.h" +#include "nsString.h" + +class nsIDOMWindow; +class nsIObserver; +class nsIPrintSettings; + +class nsPrintProgress : public nsIPrintProgress { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIPRINTPROGRESS + NS_DECL_NSIWEBPROGRESSLISTENER + + explicit nsPrintProgress(nsIPrintSettings* aPrintSettings); + + protected: + virtual ~nsPrintProgress(); + + private: + nsresult ReleaseListeners(); + + bool m_closeProgress; + bool m_processCanceled; + nsString m_pendingStatus; + int32_t m_pendingStateFlags; + nsresult m_pendingStateValue; + nsCOMPtr<nsIDOMWindow> m_dialog; + nsCOMArray<nsIWebProgressListener> m_listenerList; + nsCOMPtr<nsIObserver> m_observer; + nsCOMPtr<nsIPrintSettings> m_PrintSetting; +}; + +#endif diff --git a/toolkit/components/printingui/nsPrintProgressParams.cpp b/toolkit/components/printingui/nsPrintProgressParams.cpp new file mode 100644 index 0000000000..39086d49e7 --- /dev/null +++ b/toolkit/components/printingui/nsPrintProgressParams.cpp @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsPrintProgressParams.h" +#include "nsReadableUtils.h" + +NS_IMPL_ISUPPORTS(nsPrintProgressParams, nsIPrintProgressParams) + +nsPrintProgressParams::nsPrintProgressParams() = default; + +nsPrintProgressParams::~nsPrintProgressParams() = default; + +NS_IMETHODIMP +nsPrintProgressParams::GetDocTitle(nsAString& aDocTitle) { + aDocTitle = mDocTitle; + return NS_OK; +} + +NS_IMETHODIMP +nsPrintProgressParams::SetDocTitle(const nsAString& aDocTitle) { + mDocTitle = aDocTitle; + return NS_OK; +} + +NS_IMETHODIMP +nsPrintProgressParams::GetDocURL(nsAString& aDocURL) { + aDocURL = mDocURL; + return NS_OK; +} + +NS_IMETHODIMP +nsPrintProgressParams::SetDocURL(const nsAString& aDocURL) { + mDocURL = aDocURL; + return NS_OK; +} diff --git a/toolkit/components/printingui/nsPrintProgressParams.h b/toolkit/components/printingui/nsPrintProgressParams.h new file mode 100644 index 0000000000..fff8c077c5 --- /dev/null +++ b/toolkit/components/printingui/nsPrintProgressParams.h @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef __nsPrintProgressParams_h +#define __nsPrintProgressParams_h + +#include "nsIPrintProgressParams.h" +#include "nsString.h" + +class nsPrintProgressParams : public nsIPrintProgressParams { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTPROGRESSPARAMS + + nsPrintProgressParams(); + + protected: + virtual ~nsPrintProgressParams(); + + private: + nsString mDocTitle; + nsString mDocURL; +}; + +#endif diff --git a/toolkit/components/printingui/nsPrintingPromptService.cpp b/toolkit/components/printingui/nsPrintingPromptService.cpp new file mode 100644 index 0000000000..0ee201ca82 --- /dev/null +++ b/toolkit/components/printingui/nsPrintingPromptService.cpp @@ -0,0 +1,225 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsPrintingPromptService.h" + +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/RefPtr.h" +#include "mozilla/StaticPtr.h" +#include "nsISupportsUtils.h" +#include "nsString.h" +#include "nsIPrintDialogService.h" +#include "nsPIDOMWindow.h" +#include "nsServiceManagerUtils.h" +#include "nsXULAppAPI.h" + +// Printing Progress Includes +#if !defined(XP_MACOSX) +# include "nsPrintProgress.h" +# include "nsPrintProgressParams.h" + +static const char* kPrintProgressDialogURL = + "chrome://global/content/printProgress.xhtml"; +static const char* kPrtPrvProgressDialogURL = + "chrome://global/content/printPreviewProgress.xhtml"; +#endif + +using namespace mozilla; + +NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, + nsIWebProgressListener) + +StaticRefPtr<nsPrintingPromptService> sSingleton; + +/* static */ +already_AddRefed<nsPrintingPromptService> +nsPrintingPromptService::GetSingleton() { + MOZ_ASSERT(XRE_IsParentProcess(), + "The content process must use nsPrintingProxy"); + + if (!sSingleton) { + sSingleton = new nsPrintingPromptService(); + sSingleton->Init(); + ClearOnShutdown(&sSingleton); + } + + return do_AddRef(sSingleton); +} + +nsPrintingPromptService::nsPrintingPromptService() = default; + +nsPrintingPromptService::~nsPrintingPromptService() = default; + +nsresult nsPrintingPromptService::Init() { +#if !defined(XP_MACOSX) + nsresult rv; + mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); + return rv; +#else + return NS_OK; +#endif +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy* parent, + nsIPrintSettings* printSettings) { + NS_ENSURE_ARG(printSettings); + + nsCOMPtr<nsIPrintDialogService> dlgPrint( + do_GetService(NS_PRINTDIALOGSERVICE_CONTRACTID)); + if (dlgPrint) + return dlgPrint->Show(nsPIDOMWindowOuter::From(parent), printSettings); + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPrintProgressDialog( + mozIDOMWindowProxy* parent, + nsIPrintSettings* printSettings, // ok to be null + nsIObserver* openDialogObserver, // ok to be null + bool isForPrinting, nsIWebProgressListener** webProgressListener, + nsIPrintProgressParams** printProgressParams, bool* notifyOnOpen) { +#if !defined(XP_MACOSX) + NS_ENSURE_ARG(webProgressListener); + NS_ENSURE_ARG(printProgressParams); + NS_ENSURE_ARG(notifyOnOpen); + + *notifyOnOpen = false; + if (mPrintProgress) { + *webProgressListener = nullptr; + *printProgressParams = nullptr; + return NS_ERROR_FAILURE; + } + + nsPrintProgress* prtProgress = new nsPrintProgress(printSettings); + mPrintProgress = prtProgress; + mWebProgressListener = prtProgress; + + nsCOMPtr<nsIPrintProgressParams> prtProgressParams = + new nsPrintProgressParams(); + + nsCOMPtr<mozIDOMWindowProxy> parentWindow = parent; + + if (mWatcher && !parentWindow) { + mWatcher->GetActiveWindow(getter_AddRefs(parentWindow)); + } + + if (parentWindow) { + mPrintProgress->OpenProgressDialog( + parentWindow, + isForPrinting ? kPrintProgressDialogURL : kPrtPrvProgressDialogURL, + prtProgressParams, openDialogObserver, notifyOnOpen); + } + + prtProgressParams.forget(printProgressParams); + NS_ADDREF(*webProgressListener = this); + + return NS_OK; +#else + return NS_ERROR_NOT_IMPLEMENTED; +#endif +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPageSetupDialog(mozIDOMWindowProxy* parent, + nsIPrintSettings* printSettings) { + NS_ENSURE_ARG(printSettings); + + nsCOMPtr<nsIPrintDialogService> dlgPrint( + do_GetService(NS_PRINTDIALOGSERVICE_CONTRACTID)); + if (dlgPrint) + return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent), + printSettings); + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnStateChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aStateFlags, nsresult aStatus) { +#if !defined(XP_MACOSX) + if ((aStateFlags & STATE_STOP) && mWebProgressListener) { + mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, + aStatus); + if (mPrintProgress) { + mPrintProgress->CloseProgressDialog(true); + } + mPrintProgress = nullptr; + mWebProgressListener = nullptr; + } +#endif + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnProgressChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + int32_t aCurSelfProgress, + int32_t aMaxSelfProgress, + int32_t aCurTotalProgress, + int32_t aMaxTotalProgress) { +#if !defined(XP_MACOSX) + if (mWebProgressListener) { + return mWebProgressListener->OnProgressChange( + aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, + aCurTotalProgress, aMaxTotalProgress); + } +#endif + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnLocationChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsIURI* location, uint32_t aFlags) { +#if !defined(XP_MACOSX) + if (mWebProgressListener) { + return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, + location, aFlags); + } +#endif + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnStatusChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, nsresult aStatus, + const char16_t* aMessage) { +#if !defined(XP_MACOSX) + if (mWebProgressListener) { + return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, + aMessage); + } +#endif + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnSecurityChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aState) { +#if !defined(XP_MACOSX) + if (mWebProgressListener) { + return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, + aState); + } +#endif + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnContentBlockingEvent(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aEvent) { +#if !defined(XP_MACOSX) + if (mWebProgressListener) { + return mWebProgressListener->OnContentBlockingEvent(aWebProgress, aRequest, + aEvent); + } +#endif + return NS_OK; +} diff --git a/toolkit/components/printingui/nsPrintingPromptService.h b/toolkit/components/printingui/nsPrintingPromptService.h new file mode 100644 index 0000000000..fa3504a5d1 --- /dev/null +++ b/toolkit/components/printingui/nsPrintingPromptService.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef __nsPrintingPromptService_h +#define __nsPrintingPromptService_h + +// {E042570C-62DE-4bb6-A6E0-798E3C07B4DF} +#define NS_PRINTINGPROMPTSERVICE_CID \ + { \ + 0xe042570c, 0x62de, 0x4bb6, { \ + 0xa6, 0xe0, 0x79, 0x8e, 0x3c, 0x7, 0xb4, 0xdf \ + } \ + } +#define NS_PRINTINGPROMPTSERVICE_CONTRACTID \ + "@mozilla.org/embedcomp/printingprompt-service;1" + +#include "nsCOMPtr.h" +#include "nsIPrintingPromptService.h" +#include "nsIWindowWatcher.h" + +// Printing Progress Includes +#include "nsIWebProgressListener.h" +#if !defined(XP_MACOSX) +# include "nsPrintProgress.h" + +class nsIDOMWindow; +class nsIDialogParamBlock; +#endif + +class nsPrintingPromptService final : public nsIPrintingPromptService, + public nsIWebProgressListener { + public: + static already_AddRefed<nsPrintingPromptService> GetSingleton(); + + NS_DECL_NSIPRINTINGPROMPTSERVICE + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_ISUPPORTS + + protected: + nsPrintingPromptService(); + virtual ~nsPrintingPromptService(); + nsresult Init(); + + private: +#if !defined(XP_MACOSX) + nsCOMPtr<nsIWindowWatcher> mWatcher; + nsCOMPtr<nsIPrintProgress> mPrintProgress; + nsCOMPtr<nsIWebProgressListener> mWebProgressListener; +#endif +}; + +#endif |