diff options
Diffstat (limited to 'embedding/components/printingui')
43 files changed, 4706 insertions, 0 deletions
diff --git a/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl b/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl new file mode 100644 index 000000000..1da29ef87 --- /dev/null +++ b/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl @@ -0,0 +1,35 @@ +/* -*- 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(); +}; + +} // namespace embedding +} // namespace mozilla diff --git a/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl b/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl new file mode 100644 index 000000000..3e436892e --- /dev/null +++ b/embedding/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/embedding/components/printingui/ipc/PPrinting.ipdl b/embedding/components/printingui/ipc/PPrinting.ipdl new file mode 100644 index 000000000..0b4a1cf64 --- /dev/null +++ b/embedding/components/printingui/ipc/PPrinting.ipdl @@ -0,0 +1,48 @@ +/* -*- 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: + sync ShowProgress(PBrowser browser, + PPrintProgressDialog printProgressDialog, + nullable PRemotePrintJob remotePrintJob, + bool isForPrinting) + returns(bool notifyOnOpen, + nsresult rv); + + 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/embedding/components/printingui/ipc/PPrintingTypes.ipdlh b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh new file mode 100644 index 000000000..084047baf --- /dev/null +++ b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh @@ -0,0 +1,126 @@ +/* -*- 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; + int32_t startPageRange; + int32_t endPageRange; + 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; + short printRange; + nsString title; + nsString docURL; + nsString headerStrLeft; + nsString headerStrCenter; + nsString headerStrRight; + nsString footerStrLeft; + nsString footerStrCenter; + nsString footerStrRight; + + short howToEnableFrameUI; + bool isCancelled; + short printFrameTypeUsage; + short printFrameType; + bool printSilent; + bool shrinkToFit; + bool showPrintProgress; + + nsString paperName; + short paperData; + double paperWidth; + double paperHeight; + short paperSizeUnit; + bool printReversed; + bool printInColor; + int32_t orientation; + int32_t numCopies; + nsString printerName; + bool printToFile; + nsString toFileName; + short outputFormat; + int32_t printPageDelay; + int32_t resolution; + int32_t duplex; + bool isInitializedFromPrinter; + bool isInitializedFromPrefs; + int32_t optionFlags; + + /* Windows-specific things */ + nsString driverName; + nsString deviceName; + double printableWidthInInches; + double printableHeightInInches; + bool isFramesetDocument; + bool isFramesetFrameSelected; + bool isIFrameSelected; + bool isRangeSelection; + 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; + + /** + * OS X specific things. + */ + nsString printJobName; + bool printAllPages; + bool mustCollate; + nsString disposition; + /** TODO: Is there an "unsigned short" primitive? **/ + short pagesAcross; + short pagesDown; + double printTime; + bool detailedErrorReporting; + nsString faxNumber; + bool addHeaderAndFooter; + bool fileNameExtensionHidden; + /* + * Holds the scaling factor from the Print dialog when shrink + * to fit is not used. This is needed by the child when it + * isn't using remote printing. When shrink to fit is enabled + * (default), print dialog code ensures this value is 1.0. + */ + float scalingFactor; + /* + * Scaling factor for converting from OS X native paper size + * units to inches. + */ + float widthScale; + float heightScale; + double adjustedPaperWidth; + double adjustedPaperHeight; +}; + +} // namespace embedding +} // namespace mozilla diff --git a/embedding/components/printingui/ipc/PrintDataUtils.cpp b/embedding/components/printingui/ipc/PrintDataUtils.cpp new file mode 100644 index 000000000..30e2075b6 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintDataUtils.cpp @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 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/. */
+
+#include "PrintDataUtils.h"
+#include "nsIPrintSettings.h"
+#include "nsIServiceManager.h"
+#include "nsIWebBrowserPrint.h"
+#include "nsXPIDLString.h"
+
+namespace mozilla {
+namespace embedding {
+
+/**
+ * MockWebBrowserPrint is a mostly useless implementation of nsIWebBrowserPrint,
+ * but wraps a PrintData so that it's able to return information to print
+ * settings dialogs that need an nsIWebBrowserPrint to interrogate.
+ */
+
+NS_IMPL_ISUPPORTS(MockWebBrowserPrint, nsIWebBrowserPrint);
+
+MockWebBrowserPrint::MockWebBrowserPrint(const PrintData &aData)
+ : mData(aData)
+{
+ MOZ_COUNT_CTOR(MockWebBrowserPrint);
+}
+
+MockWebBrowserPrint::~MockWebBrowserPrint()
+{
+ MOZ_COUNT_DTOR(MockWebBrowserPrint);
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetGlobalPrintSettings(nsIPrintSettings **aGlobalPrintSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetCurrentPrintSettings(nsIPrintSettings **aCurrentPrintSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetCurrentChildDOMWindow(mozIDOMWindowProxy **aCurrentPrintSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetDoingPrint(bool *aDoingPrint)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetDoingPrintPreview(bool *aDoingPrintPreview)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsFramesetDocument(bool *aIsFramesetDocument)
+{
+ *aIsFramesetDocument = mData.isFramesetDocument();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected)
+{
+ *aIsFramesetFrameSelected = mData.isFramesetFrameSelected();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsIFrameSelected(bool *aIsIFrameSelected)
+{
+ *aIsIFrameSelected = mData.isIFrameSelected();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsRangeSelection(bool *aIsRangeSelection)
+{
+ *aIsRangeSelection = mData.isRangeSelection();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::Print(nsIPrintSettings* aThePrintSettings,
+ nsIWebProgressListener* aWPListener)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::PrintPreview(nsIPrintSettings* aThePrintSettings,
+ mozIDOMWindowProxy* aChildDOMWin,
+ nsIWebProgressListener* aWPListener)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::PrintPreviewNavigate(int16_t aNavType,
+ int32_t aPageNum)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::Cancel()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::EnumerateDocumentNames(uint32_t* aCount,
+ char16_t*** aResult)
+{
+ *aCount = 0;
+ *aResult = nullptr;
+
+ if (mData.printJobName().IsEmpty()) {
+ return NS_OK;
+ }
+
+ // The only consumer that cares about this is the OS X printing
+ // dialog, and even then, it only cares about the first document
+ // name. That's why we only send a single document name through
+ // PrintData.
+ char16_t** array = (char16_t**) moz_xmalloc(sizeof(char16_t*));
+ array[0] = ToNewUnicode(mData.printJobName());
+
+ *aCount = 1;
+ *aResult = array;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::ExitPrintPreview()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+} // namespace embedding
+} // namespace mozilla
+
diff --git a/embedding/components/printingui/ipc/PrintDataUtils.h b/embedding/components/printingui/ipc/PrintDataUtils.h new file mode 100644 index 000000000..da313b2f3 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintDataUtils.h @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 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_PrintDataUtils_h
+#define mozilla_embedding_PrintDataUtils_h
+
+#include "mozilla/embedding/PPrinting.h"
+#include "nsIWebBrowserPrint.h"
+
+/**
+ * nsIPrintSettings and nsIWebBrowserPrint information is sent back and forth
+ * across PPrinting via the PrintData struct. These are utilities for
+ * manipulating PrintData that can be used on either side of the communications
+ * channel.
+ */
+
+namespace mozilla {
+namespace embedding {
+
+class MockWebBrowserPrint final : public nsIWebBrowserPrint
+{
+public:
+ explicit MockWebBrowserPrint(const PrintData &aData);
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEBBROWSERPRINT
+
+private:
+ ~MockWebBrowserPrint();
+ PrintData mData;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/embedding/components/printingui/ipc/PrintProgressDialogChild.cpp b/embedding/components/printingui/ipc/PrintProgressDialogChild.cpp new file mode 100644 index 000000000..a6dc5de4e --- /dev/null +++ b/embedding/components/printingui/ipc/PrintProgressDialogChild.cpp @@ -0,0 +1,132 @@ +/* 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 "PrintProgressDialogChild.h" + +class nsIWebProgress; +class nsIRequest; + +using mozilla::Unused; + +namespace mozilla { +namespace embedding { + +NS_IMPL_ISUPPORTS(PrintProgressDialogChild, + nsIWebProgressListener, + nsIPrintProgressParams) + +PrintProgressDialogChild::PrintProgressDialogChild( + nsIObserver* aOpenObserver) : + mOpenObserver(aOpenObserver) +{ + MOZ_COUNT_CTOR(PrintProgressDialogChild); +} + +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); + MOZ_COUNT_DTOR(PrintProgressDialogChild); +} + +bool +PrintProgressDialogChild::RecvDialogOpened() +{ + // nsPrintEngine'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 true; +} + +// 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; +} + +// nsIPrintProgressParams + +NS_IMETHODIMP PrintProgressDialogChild::GetDocTitle(char16_t* *aDocTitle) +{ + NS_ENSURE_ARG(aDocTitle); + + *aDocTitle = ToNewUnicode(mDocTitle); + return NS_OK; +} + +NS_IMETHODIMP PrintProgressDialogChild::SetDocTitle(const char16_t* aDocTitle) +{ + mDocTitle = aDocTitle; + Unused << SendDocTitleChange(nsString(aDocTitle)); + return NS_OK; +} + +NS_IMETHODIMP PrintProgressDialogChild::GetDocURL(char16_t **aDocURL) +{ + NS_ENSURE_ARG(aDocURL); + + *aDocURL = ToNewUnicode(mDocURL); + return NS_OK; +} + +NS_IMETHODIMP PrintProgressDialogChild::SetDocURL(const char16_t* aDocURL) +{ + mDocURL = aDocURL; + Unused << SendDocURLChange(nsString(aDocURL)); + return NS_OK; +} + +} // namespace embedding +} // namespace mozilla diff --git a/embedding/components/printingui/ipc/PrintProgressDialogChild.h b/embedding/components/printingui/ipc/PrintProgressDialogChild.h new file mode 100644 index 000000000..b0a7105d7 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintProgressDialogChild.h @@ -0,0 +1,40 @@ +/* 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 "nsIPrintProgressParams.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); + + virtual bool RecvDialogOpened() override; + +private: + virtual ~PrintProgressDialogChild(); + nsCOMPtr<nsIObserver> mOpenObserver; + nsString mDocTitle; + nsString mDocURL; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/embedding/components/printingui/ipc/PrintProgressDialogParent.cpp b/embedding/components/printingui/ipc/PrintProgressDialogParent.cpp new file mode 100644 index 000000000..6e34704ff --- /dev/null +++ b/embedding/components/printingui/ipc/PrintProgressDialogParent.cpp @@ -0,0 +1,113 @@ +/* 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 "nsIPrintProgressParams.h" +#include "nsIWebProgressListener.h" +#include "PrintProgressDialogParent.h" + +using mozilla::Unused; + +namespace mozilla { +namespace embedding { + +NS_IMPL_ISUPPORTS(PrintProgressDialogParent, nsIObserver) + +PrintProgressDialogParent::PrintProgressDialogParent() : + mActive(true) +{ + MOZ_COUNT_CTOR(PrintProgressDialogParent); +} + +PrintProgressDialogParent::~PrintProgressDialogParent() +{ + MOZ_COUNT_DTOR(PrintProgressDialogParent); +} + +void +PrintProgressDialogParent::SetWebProgressListener(nsIWebProgressListener* aListener) +{ + mWebProgressListener = aListener; +} + +void +PrintProgressDialogParent::SetPrintProgressParams(nsIPrintProgressParams* aParams) +{ + mPrintProgressParams = aParams; +} + +bool +PrintProgressDialogParent::RecvStateChange(const long& stateFlags, + const nsresult& status) +{ + if (mWebProgressListener) { + mWebProgressListener->OnStateChange(nullptr, nullptr, stateFlags, status); + } + return true; +} + +bool +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 true; +} + +bool +PrintProgressDialogParent::RecvDocTitleChange(const nsString& newTitle) +{ + if (mPrintProgressParams) { + mPrintProgressParams->SetDocTitle(newTitle.get()); + } + return true; +} + +bool +PrintProgressDialogParent::RecvDocURLChange(const nsString& newURL) +{ + if (mPrintProgressParams) { + mPrintProgressParams->SetDocURL(newURL.get()); + } + return true; +} + +void +PrintProgressDialogParent::ActorDestroy(ActorDestroyReason aWhy) +{ +} + +bool +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 true; +} + +// nsIObserver +NS_IMETHODIMP +PrintProgressDialogParent::Observe(nsISupports *aSubject, const char *aTopic, + const char16_t *aData) +{ + if (mActive) { + Unused << SendDialogOpened(); + } 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/embedding/components/printingui/ipc/PrintProgressDialogParent.h b/embedding/components/printingui/ipc/PrintProgressDialogParent.h new file mode 100644 index 000000000..540609162 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintProgressDialogParent.h @@ -0,0 +1,64 @@ +/* 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 bool + RecvStateChange( + const long& stateFlags, + const nsresult& status) override; + + virtual bool + RecvProgressChange( + const long& curSelfProgress, + const long& maxSelfProgress, + const long& curTotalProgress, + const long& maxTotalProgress) override; + + virtual bool + RecvDocTitleChange(const nsString& newTitle) override; + + virtual bool + RecvDocURLChange(const nsString& newURL) override; + + virtual void + ActorDestroy(ActorDestroyReason aWhy) override; + + virtual bool + Recv__delete__() override; + +private: + virtual ~PrintProgressDialogParent(); + + nsCOMPtr<nsIWebProgressListener> mWebProgressListener; + nsCOMPtr<nsIPrintProgressParams> mPrintProgressParams; + bool mActive; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp b/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp new file mode 100644 index 000000000..ee9c5de59 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp @@ -0,0 +1,38 @@ +/* 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); +} + +bool +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 true; +} + +} // namespace embedding +} // namespace mozilla diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogChild.h b/embedding/components/printingui/ipc/PrintSettingsDialogChild.h new file mode 100644 index 000000000..6db60e221 --- /dev/null +++ b/embedding/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 bool 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/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp b/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp new file mode 100644 index 000000000..016677d96 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp @@ -0,0 +1,28 @@ +/* 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/embedding/components/printingui/ipc/PrintSettingsDialogParent.h b/embedding/components/printingui/ipc/PrintSettingsDialogParent.h new file mode 100644 index 000000000..e655903e7 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintSettingsDialogParent.h @@ -0,0 +1,29 @@ +/* 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/embedding/components/printingui/ipc/PrintingParent.cpp b/embedding/components/printingui/ipc/PrintingParent.cpp new file mode 100644 index 000000000..46469844a --- /dev/null +++ b/embedding/components/printingui/ipc/PrintingParent.cpp @@ -0,0 +1,336 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/TabParent.h" +#include "mozilla/Preferences.h" +#include "mozilla/Unused.h" +#include "nsIContent.h" +#include "nsIDocument.h" +#include "nsIDOMWindow.h" +#include "nsIPrintingPromptService.h" +#include "nsIPrintProgressParams.h" +#include "nsIPrintSettingsService.h" +#include "nsIServiceManager.h" +#include "nsServiceManagerUtils.h" +#include "nsIWebProgressListener.h" +#include "PrintingParent.h" +#include "PrintDataUtils.h" +#include "PrintProgressDialogParent.h" +#include "PrintSettingsDialogParent.h" +#include "mozilla/layout/RemotePrintJobParent.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::layout; + +namespace mozilla { +namespace embedding { +bool +PrintingParent::RecvShowProgress(PBrowserParent* parent, + PPrintProgressDialogParent* printProgressDialog, + PRemotePrintJobParent* remotePrintJob, + const bool& isForPrinting, + bool* notifyOnOpen, + nsresult* result) +{ + *result = NS_ERROR_FAILURE; + *notifyOnOpen = false; + + nsCOMPtr<nsPIDOMWindowOuter> parentWin = DOMWindowFromBrowserParent(parent); + if (!parentWin) { + return true; + } + + nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1")); + + if (!pps) { + return true; + } + + PrintProgressDialogParent* dialogParent = + static_cast<PrintProgressDialogParent*>(printProgressDialog); + nsCOMPtr<nsIObserver> observer = do_QueryInterface(dialogParent); + + nsCOMPtr<nsIWebProgressListener> printProgressListener; + nsCOMPtr<nsIPrintProgressParams> printProgressParams; + + *result = pps->ShowProgress(parentWin, nullptr, nullptr, observer, + isForPrinting, + getter_AddRefs(printProgressListener), + getter_AddRefs(printProgressParams), + notifyOnOpen); + NS_ENSURE_SUCCESS(*result, true); + + 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); + + return true; +} + +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; + } + + // The initSettings we got can be wrapped using + // PrintDataUtils' MockWebBrowserPrint, which implements enough of + // nsIWebBrowserPrint to keep the dialogs happy. + nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(aData); + + // 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); + + // 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 || + Preferences::GetBool("print.always_print_silent", printSilently)) { + nsXPIDLString printerName; + rv = settings->GetPrinterName(getter_Copies(printerName)); + NS_ENSURE_SUCCESS(rv, rv); + + settings->SetIsInitializedFromPrinter(false); + mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings); + } else { + rv = pps->ShowPrintDialog(parentWin, wbp, settings); + NS_ENSURE_SUCCESS(rv, rv); + } + + if (isPrintPreview) { + // For print preview we don't want a RemotePrintJob just the settings. + rv = mPrintSettingsSvc->SerializeToPrintData(settings, nullptr, aResult); + } else { + rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob, + aResult); + } + + return rv; +} + +bool +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 << aDialog->Send__delete__(aDialog, rv); + } else { + mozilla::Unused << aDialog->Send__delete__(aDialog, resultData); + } + return true; +} + +bool +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, true); + + *aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings); + NS_ENSURE_SUCCESS(*aResult, true); + + *aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs(settings, + aUsePrinterNamePrefix, + aFlags); + + return true; +} + +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; +} + +PRemotePrintJobParent* +PrintingParent::AllocPRemotePrintJobParent() +{ + MOZ_ASSERT_UNREACHABLE("No default constructors for implementations."); + return nullptr; +} + +bool +PrintingParent::DeallocPRemotePrintJobParent(PRemotePrintJobParent* aDoomed) +{ + delete aDoomed; + return true; +} + +void +PrintingParent::ActorDestroy(ActorDestroyReason aWhy) +{ +} + +nsPIDOMWindowOuter* +PrintingParent::DOMWindowFromBrowserParent(PBrowserParent* parent) +{ + if (!parent) { + return nullptr; + } + + TabParent* tabParent = TabParent::GetFrom(parent); + if (!tabParent) { + return nullptr; + } + + nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement(); + if (!frameElement) { + return nullptr; + } + + nsCOMPtr<nsIContent> frame(do_QueryInterface(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, 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); + + mPrintSettingsSvc = + do_GetService("@mozilla.org/gfx/printsettings-service;1"); + MOZ_ASSERT(mPrintSettingsSvc); +} + +PrintingParent::~PrintingParent() +{ + MOZ_COUNT_DTOR(PrintingParent); +} + +} // namespace embedding +} // namespace mozilla + diff --git a/embedding/components/printingui/ipc/PrintingParent.h b/embedding/components/printingui/ipc/PrintingParent.h new file mode 100644 index 000000000..66f87726c --- /dev/null +++ b/embedding/components/printingui/ipc/PrintingParent.h @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sw=4 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 embedding { + +class PrintingParent final : public PPrintingParent +{ +public: + NS_INLINE_DECL_REFCOUNTING(PrintingParent) + + virtual bool + RecvShowProgress(PBrowserParent* parent, + PPrintProgressDialogParent* printProgressDialog, + PRemotePrintJobParent* remotePrintJob, + const bool& isForPrinting, + bool* notifyOnOpen, + nsresult* result); + virtual bool + RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog, + PBrowserParent* aParent, + const PrintData& aData); + + virtual bool + RecvSavePrintSettings(const PrintData& data, + const bool& usePrinterNamePrefix, + const uint32_t& flags, + nsresult* rv); + + virtual PPrintProgressDialogParent* + AllocPPrintProgressDialogParent(); + + virtual bool + DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* aActor); + + virtual PPrintSettingsDialogParent* + AllocPPrintSettingsDialogParent(); + + virtual bool + DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aActor); + + virtual PRemotePrintJobParent* + AllocPRemotePrintJobParent(); + + virtual bool + DeallocPRemotePrintJobParent(PRemotePrintJobParent* aActor); + + virtual void + ActorDestroy(ActorDestroyReason aWhy); + + 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(); + + nsPIDOMWindowOuter* + DOMWindowFromBrowserParent(PBrowserParent* parent); + + nsresult + ShowPrintDialog(PBrowserParent* parent, + const PrintData& data, + PrintData* result); + + nsCOMPtr<nsIPrintSettingsService> mPrintSettingsSvc; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/embedding/components/printingui/ipc/moz.build b/embedding/components/printingui/ipc/moz.build new file mode 100644 index 000000000..29822e652 --- /dev/null +++ b/embedding/components/printingui/ipc/moz.build @@ -0,0 +1,35 @@ +# -*- 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', + 'PrintDataUtils.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/embedding/components/printingui/ipc/nsPrintingProxy.cpp b/embedding/components/printingui/ipc/nsPrintingProxy.cpp new file mode 100644 index 000000000..353be04ee --- /dev/null +++ b/embedding/components/printingui/ipc/nsPrintingProxy.cpp @@ -0,0 +1,269 @@ +/* -*- 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); + + while(!dialog->returned()) { + NS_ProcessNextEvent(nullptr, true); + } + + 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); + + 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)); + } + } + + nsresult rv = NS_OK; + mozilla::Unused << SendShowProgress(pBrowser, dialogChild, remotePrintJob, + isForPrinting, notifyOnOpen, &rv); + if (NS_FAILED(rv)) { + return rv; + } + + // 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; +} + +NS_IMETHODIMP +nsPrintingProxy::ShowPrinterProperties(mozIDOMWindowProxy *parent, + const char16_t *printerName, + 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, 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; +} diff --git a/embedding/components/printingui/ipc/nsPrintingProxy.h b/embedding/components/printingui/ipc/nsPrintingProxy.h new file mode 100644 index 000000000..6b4d9cf5a --- /dev/null +++ b/embedding/components/printingui/ipc/nsPrintingProxy.h @@ -0,0 +1,57 @@ +/* -*- 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; +} +} + +class nsPrintingProxy: public nsIPrintingPromptService, + public mozilla::embedding::PPrintingChild +{ + virtual ~nsPrintingProxy(); + +public: + nsPrintingProxy(); + + static already_AddRefed<nsPrintingProxy> GetInstance(); + + nsresult Init(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTINGPROMPTSERVICE + + nsresult SavePrintSettings(nsIPrintSettings* aPS, + bool aUsePrinterNamePrefix, + uint32_t aFlags); + + virtual PPrintProgressDialogChild* + AllocPPrintProgressDialogChild() override; + + virtual bool + DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor) override; + + virtual PPrintSettingsDialogChild* + AllocPPrintSettingsDialogChild() override; + + virtual bool + DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor) override; + + virtual PRemotePrintJobChild* + AllocPRemotePrintJobChild() override; + + virtual bool + DeallocPRemotePrintJobChild(PRemotePrintJobChild* aActor) override; +}; + +#endif + diff --git a/embedding/components/printingui/mac/moz.build b/embedding/components/printingui/mac/moz.build new file mode 100644 index 000000000..aa3047c53 --- /dev/null +++ b/embedding/components/printingui/mac/moz.build @@ -0,0 +1,16 @@ +# -*- 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/. + +UNIFIED_SOURCES += [ + 'nsPrintProgress.cpp', + 'nsPrintProgressParams.cpp', +] + +SOURCES += [ + 'nsPrintingPromptServiceX.mm', +] + +FINAL_LIBRARY = 'xul' diff --git a/embedding/components/printingui/mac/nsPrintProgress.cpp b/embedding/components/printingui/mac/nsPrintProgress.cpp new file mode 100644 index 000000000..0ae0a63d9 --- /dev/null +++ b/embedding/components/printingui/mac/nsPrintProgress.cpp @@ -0,0 +1,213 @@ +/* -*- 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 "nsIBaseWindow.h" +#include "nsXPCOM.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" +#include "nsPIDOMWindow.h" + +NS_IMPL_ADDREF(nsPrintProgress) +NS_IMPL_RELEASE(nsPrintProgress) + +NS_INTERFACE_MAP_BEGIN(nsPrintProgress) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback) + NS_INTERFACE_MAP_ENTRY(nsIPrintProgress) + NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) +NS_INTERFACE_MAP_END_THREADSAFE + + +nsPrintProgress::nsPrintProgress() +{ + m_closeProgress = false; + m_processCanceled = false; + m_pendingStateFlags = -1; + m_pendingStateValue = NS_OK; +} + +nsPrintProgress::~nsPrintProgress() +{ + (void)ReleaseListeners(); +} + +NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(mozIDOMWindowProxy *parent, + const char *dialogURL, + nsISupports *parameters, + nsIObserver *openDialogObserver, + bool *notifyOnOpen) +{ + MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress " + "implementation for OS X returns " + "NS_ERROR_NOT_IMPLEMENTED, so we should never get " + "here."); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose) +{ + MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress " + "implementation for OS X returns " + "NS_ERROR_NOT_IMPLEMENTED, so we should never get " + "here."); + return NS_ERROR_NOT_IMPLEMENTED; +} + +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) +{ + 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) +{ + 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) +{ + 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_OK; +} + +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 state) +{ + return NS_OK; +} + +nsresult nsPrintProgress::ReleaseListeners() +{ + m_listenerList.Clear(); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status) +{ + return OnStatusChange(nullptr, nullptr, NS_OK, status); +} + +NS_IMETHODIMP nsPrintProgress::StartMeteors() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::StopMeteors() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell, + mozIDOMWindowProxy *window) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::CloseWindow() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + diff --git a/embedding/components/printingui/mac/nsPrintProgress.h b/embedding/components/printingui/mac/nsPrintProgress.h new file mode 100644 index 000000000..938558c3e --- /dev/null +++ b/embedding/components/printingui/mac/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 "nsIPrintStatusFeedback.h" +#include "nsIObserver.h" +#include "nsString.h" + +class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIPRINTPROGRESS + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSIPRINTSTATUSFEEDBACK + + nsPrintProgress(); + +protected: + virtual ~nsPrintProgress(); + +private: + nsresult ReleaseListeners(); + + bool m_closeProgress; + bool m_processCanceled; + nsString m_pendingStatus; + int32_t m_pendingStateFlags; + nsresult m_pendingStateValue; + // XXX This member is read-only. + nsCOMPtr<mozIDOMWindowProxy> m_dialog; + nsCOMArray<nsIWebProgressListener> m_listenerList; + nsCOMPtr<nsIObserver> m_observer; +}; + +#endif diff --git a/embedding/components/printingui/mac/nsPrintProgressParams.cpp b/embedding/components/printingui/mac/nsPrintProgressParams.cpp new file mode 100644 index 000000000..eba86b298 --- /dev/null +++ b/embedding/components/printingui/mac/nsPrintProgressParams.cpp @@ -0,0 +1,47 @@ +/* -*- 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() +{ +} + +nsPrintProgressParams::~nsPrintProgressParams() +{ +} + +NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle) +{ + NS_ENSURE_ARG(aDocTitle); + + *aDocTitle = ToNewUnicode(mDocTitle); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle) +{ + mDocTitle = aDocTitle; + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL) +{ + NS_ENSURE_ARG(aDocURL); + + *aDocURL = ToNewUnicode(mDocURL); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL) +{ + mDocURL = aDocURL; + return NS_OK; +} + diff --git a/embedding/components/printingui/mac/nsPrintProgressParams.h b/embedding/components/printingui/mac/nsPrintProgressParams.h new file mode 100644 index 000000000..65c00d98f --- /dev/null +++ b/embedding/components/printingui/mac/nsPrintProgressParams.h @@ -0,0 +1,28 @@ +/* -*- 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/embedding/components/printingui/mac/nsPrintingPromptService.h b/embedding/components/printingui/mac/nsPrintingPromptService.h new file mode 100644 index 000000000..0334db223 --- /dev/null +++ b/embedding/components/printingui/mac/nsPrintingPromptService.h @@ -0,0 +1,43 @@ +/* -*- 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 "nsPIPromptService.h" +#include "nsIWindowWatcher.h" + +// Printing Progress Includes +#include "nsPrintProgress.h" +#include "nsIWebProgressListener.h" + +class nsPrintingPromptService: public nsIPrintingPromptService, + public nsIWebProgressListener +{ +public: + nsPrintingPromptService(); + + nsresult Init(); + + NS_DECL_NSIPRINTINGPROMPTSERVICE + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_ISUPPORTS + +protected: + virtual ~nsPrintingPromptService(); + +private: + nsCOMPtr<nsIPrintProgress> mPrintProgress; +}; + +#endif diff --git a/embedding/components/printingui/mac/nsPrintingPromptServiceX.mm b/embedding/components/printingui/mac/nsPrintingPromptServiceX.mm new file mode 100644 index 000000000..3b956100b --- /dev/null +++ b/embedding/components/printingui/mac/nsPrintingPromptServiceX.mm @@ -0,0 +1,128 @@ +/* -*- 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 "nsPrintingPromptService.h" + +#include "nsCOMPtr.h" +#include "nsServiceManagerUtils.h" +#include "nsObjCExceptions.h" + +#include "nsIPrintingPromptService.h" +#include "nsIFactory.h" +#include "nsIPrintDialogService.h" +#include "nsPIDOMWindow.h" + +//***************************************************************************** +// nsPrintingPromptService +//***************************************************************************** + +NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener) + +nsPrintingPromptService::nsPrintingPromptService() +{ +} + +nsPrintingPromptService::~nsPrintingPromptService() +{ +} + +nsresult nsPrintingPromptService::Init() +{ + return NS_OK; +} + +//***************************************************************************** +// nsPrintingPromptService::nsIPrintingPromptService +//***************************************************************************** + +NS_IMETHODIMP +nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService( + NS_PRINTDIALOGSERVICE_CONTRACTID)); + if (dlgPrint) { + return dlgPrint->Show(nsPIDOMWindowOuter::From(parent), printSettings, + webBrowserPrint); + } + + return NS_ERROR_FAILURE; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +NS_IMETHODIMP +nsPrintingPromptService::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) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService( + NS_PRINTDIALOGSERVICE_CONTRACTID)); + if (dlgPrint) { + return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent), printSettings); + } + + return NS_ERROR_FAILURE; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + + +//***************************************************************************** +// nsPrintingPromptService::nsIWebProgressListener +//***************************************************************************** + +NS_IMETHODIMP +nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus) +{ + return NS_OK; +} + +/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ +NS_IMETHODIMP +nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress) +{ + return NS_OK; +} + +/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */ +NS_IMETHODIMP +nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags) +{ + return NS_OK; +} + +/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ +NS_IMETHODIMP +nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage) +{ + return NS_OK; +} + +/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ +NS_IMETHODIMP +nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state) +{ + return NS_OK; +} diff --git a/embedding/components/printingui/moz.build b/embedding/components/printingui/moz.build new file mode 100644 index 000000000..ea9ece413 --- /dev/null +++ b/embedding/components/printingui/moz.build @@ -0,0 +1,17 @@ +# -*- 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/. + +toolkit = CONFIG['MOZ_WIDGET_TOOLKIT'] + +DIRS += ['ipc'] + +if CONFIG['NS_PRINTING']: + if toolkit == 'windows': + DIRS += ['win'] + elif toolkit == 'cocoa': + DIRS += ['mac'] + elif CONFIG['MOZ_PDF_PRINTING']: + DIRS += ['unixshared'] diff --git a/embedding/components/printingui/unixshared/moz.build b/embedding/components/printingui/unixshared/moz.build new file mode 100644 index 000000000..b204f402f --- /dev/null +++ b/embedding/components/printingui/unixshared/moz.build @@ -0,0 +1,13 @@ +# -*- 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/. + +UNIFIED_SOURCES += [ + 'nsPrintingPromptService.cpp', + 'nsPrintProgress.cpp', + 'nsPrintProgressParams.cpp', +] + +FINAL_LIBRARY = 'xul' diff --git a/embedding/components/printingui/unixshared/nsPrintProgress.cpp b/embedding/components/printingui/unixshared/nsPrintProgress.cpp new file mode 100644 index 000000000..1a871c008 --- /dev/null +++ b/embedding/components/printingui/unixshared/nsPrintProgress.cpp @@ -0,0 +1,267 @@ +/* -*- 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 "nsArray.h" +#include "nsIBaseWindow.h" +#include "nsIDocShell.h" +#include "nsIDocShellTreeOwner.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIXULWindow.h" +#include "nsXPCOM.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" +#include "nsPIDOMWindow.h" + + +NS_IMPL_ADDREF(nsPrintProgress) +NS_IMPL_RELEASE(nsPrintProgress) + +NS_INTERFACE_MAP_BEGIN(nsPrintProgress) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback) + NS_INTERFACE_MAP_ENTRY(nsIPrintProgress) + NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) +NS_INTERFACE_MAP_END_THREADSAFE + + +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, /*weak =*/ false); + + array->AppendElement(parameters, /*weak =*/ false); + + // 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. + auto* pParentWindow = nsPIDOMWindowOuter::From(parent); + nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell(); + NS_ENSURE_STATE(docShell); + + nsCOMPtr<nsIDocShellTreeOwner> owner; + docShell->GetTreeOwner(getter_AddRefs(owner)); + + nsCOMPtr<nsIXULWindow> ownerXULWindow = do_GetInterface(owner); + nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerXULWindow); + NS_ENSURE_STATE(ownerWindow); + + nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = nsPIDOMWindowOuter::From(ownerWindow); + + // Open the dialog. + nsCOMPtr<nsPIDOMWindowOuter> newWindow; + + rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL), + NS_LITERAL_STRING("_blank"), + NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"), + array, getter_AddRefs(newWindow)); + } + + 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(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) +{ + 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) +{ + 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 state) +{ + return NS_OK; +} + +nsresult nsPrintProgress::ReleaseListeners() +{ + m_listenerList.Clear(); + + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status) +{ + return OnStatusChange(nullptr, nullptr, NS_OK, status); +} + +NS_IMETHODIMP nsPrintProgress::StartMeteors() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::StopMeteors() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell, mozIDOMWindowProxy *window) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::CloseWindow() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + diff --git a/embedding/components/printingui/unixshared/nsPrintProgress.h b/embedding/components/printingui/unixshared/nsPrintProgress.h new file mode 100644 index 000000000..5b60151c0 --- /dev/null +++ b/embedding/components/printingui/unixshared/nsPrintProgress.h @@ -0,0 +1,46 @@ +/* -*- 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 "nsIPrintingPromptService.h" + +#include "nsCOMArray.h" +#include "nsCOMPtr.h" +#include "nsIDOMWindow.h" +#include "nsIPrintStatusFeedback.h" +#include "nsIObserver.h" +#include "nsString.h" + +class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIPRINTPROGRESS + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSIPRINTSTATUSFEEDBACK + + 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/embedding/components/printingui/unixshared/nsPrintProgressParams.cpp b/embedding/components/printingui/unixshared/nsPrintProgressParams.cpp new file mode 100644 index 000000000..eba86b298 --- /dev/null +++ b/embedding/components/printingui/unixshared/nsPrintProgressParams.cpp @@ -0,0 +1,47 @@ +/* -*- 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() +{ +} + +nsPrintProgressParams::~nsPrintProgressParams() +{ +} + +NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle) +{ + NS_ENSURE_ARG(aDocTitle); + + *aDocTitle = ToNewUnicode(mDocTitle); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle) +{ + mDocTitle = aDocTitle; + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL) +{ + NS_ENSURE_ARG(aDocURL); + + *aDocURL = ToNewUnicode(mDocURL); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL) +{ + mDocURL = aDocURL; + return NS_OK; +} + diff --git a/embedding/components/printingui/unixshared/nsPrintProgressParams.h b/embedding/components/printingui/unixshared/nsPrintProgressParams.h new file mode 100644 index 000000000..839d0e08e --- /dev/null +++ b/embedding/components/printingui/unixshared/nsPrintProgressParams.h @@ -0,0 +1,28 @@ +/* -*- 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/embedding/components/printingui/unixshared/nsPrintingPromptService.cpp b/embedding/components/printingui/unixshared/nsPrintingPromptService.cpp new file mode 100644 index 000000000..fd10a4742 --- /dev/null +++ b/embedding/components/printingui/unixshared/nsPrintingPromptService.cpp @@ -0,0 +1,298 @@ +/* -*- Mode: C++; tab-width: 2; 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 "nsPrintingPromptService.h" + +#include "nsArray.h" +#include "nsIComponentManager.h" +#include "nsIDialogParamBlock.h" +#include "nsIDOMWindow.h" +#include "nsIServiceManager.h" +#include "nsISupportsUtils.h" +#include "nsString.h" +#include "nsIPrintDialogService.h" + +// Printing Progress Includes +#include "nsPrintProgress.h" +#include "nsPrintProgressParams.h" + +static const char *kPrintDialogURL = "chrome://global/content/printdialog.xul"; +static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul"; +static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul"; +static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul"; +static const char *kPrinterPropertiesURL = "chrome://global/content/printjoboptions.xul"; + +/**************************************************************** + ************************* ParamBlock *************************** + ****************************************************************/ + +class ParamBlock { + +public: + ParamBlock() + { + mBlock = 0; + } + ~ParamBlock() + { + NS_IF_RELEASE(mBlock); + } + nsresult Init() { + return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock); + } + nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; } + operator nsIDialogParamBlock * () const { return mBlock; } + +private: + nsIDialogParamBlock *mBlock; +}; + +/**************************************************************** + ***************** nsPrintingPromptService ********************** + ****************************************************************/ + +NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener) + +nsPrintingPromptService::nsPrintingPromptService() +{ +} + +nsPrintingPromptService::~nsPrintingPromptService() +{ +} + +nsresult +nsPrintingPromptService::Init() +{ + nsresult rv; + mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); + return rv; +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, + nsIWebBrowserPrint *webBrowserPrint, + nsIPrintSettings *printSettings) +{ + NS_ENSURE_ARG(webBrowserPrint); + NS_ENSURE_ARG(printSettings); + + // Try to access a component dialog + nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService( + NS_PRINTDIALOGSERVICE_CONTRACTID)); + if (dlgPrint) + return dlgPrint->Show(nsPIDOMWindowOuter::From(parent), + printSettings, webBrowserPrint); + + // Show the built-in dialog instead + ParamBlock block; + nsresult rv = block.Init(); + if (NS_FAILED(rv)) + return rv; + + block->SetInt(0, 0); + return DoDialog(parent, block, webBrowserPrint, printSettings, kPrintDialogURL); +} + +NS_IMETHODIMP +nsPrintingPromptService::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(webProgressListener); + NS_ENSURE_ARG(printProgressParams); + NS_ENSURE_ARG(notifyOnOpen); + + *notifyOnOpen = false; + + 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; +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, + nsIPrintSettings *printSettings, + nsIObserver *aObs) +{ + NS_ENSURE_ARG(printSettings); + + // Try to access a component dialog + nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService( + NS_PRINTDIALOGSERVICE_CONTRACTID)); + if (dlgPrint) + return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent), + printSettings); + + ParamBlock block; + nsresult rv = block.Init(); + if (NS_FAILED(rv)) + return rv; + + block->SetInt(0, 0); + return DoDialog(parent, block, nullptr, printSettings, kPageSetupDialogURL); +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, + const char16_t *printerName, + nsIPrintSettings *printSettings) +{ + /* fixme: We simply ignore the |aPrinter| argument here + * We should get the supported printer attributes from the printer and + * populate the print job options dialog with these data instead of using + * the "default set" here. + * However, this requires changes on all platforms and is another big chunk + * of patches ... ;-( + */ + NS_ENSURE_ARG(printerName); + NS_ENSURE_ARG(printSettings); + + ParamBlock block; + nsresult rv = block.Init(); + if (NS_FAILED(rv)) + return rv; + + block->SetInt(0, 0); + return DoDialog(parent, block, nullptr, printSettings, kPrinterPropertiesURL); + +} + +nsresult +nsPrintingPromptService::DoDialog(mozIDOMWindowProxy *aParent, + nsIDialogParamBlock *aParamBlock, + nsIWebBrowserPrint *aWebBrowserPrint, + nsIPrintSettings* aPS, + const char *aChromeURL) +{ + NS_ENSURE_ARG(aParamBlock); + NS_ENSURE_ARG(aPS); + NS_ENSURE_ARG(aChromeURL); + + if (!mWatcher) + return NS_ERROR_FAILURE; + + // get a parent, if at all possible + // (though we'd rather this didn't fail, it's OK if it does. so there's + // no failure or null check.) + nsCOMPtr<mozIDOMWindowProxy> activeParent; + if (!aParent) + { + mWatcher->GetActiveWindow(getter_AddRefs(activeParent)); + aParent = activeParent; + } + + // create a nsIMutableArray of the parameters + // being passed to the window + nsCOMPtr<nsIMutableArray> array = nsArray::Create(); + + nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS)); + NS_ASSERTION(psSupports, "PrintSettings must be a supports"); + array->AppendElement(psSupports, /*weak =*/ false); + + if (aWebBrowserPrint) { + nsCOMPtr<nsISupports> wbpSupports(do_QueryInterface(aWebBrowserPrint)); + NS_ASSERTION(wbpSupports, "nsIWebBrowserPrint must be a supports"); + array->AppendElement(wbpSupports, /*weak =*/ false); + } + + nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock)); + NS_ASSERTION(blkSupps, "IOBlk must be a supports"); + array->AppendElement(blkSupps, /*weak =*/ false); + + nsCOMPtr<mozIDOMWindowProxy> dialog; + nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank", + "centerscreen,chrome,modal,titlebar", array, + getter_AddRefs(dialog)); + + // if aWebBrowserPrint is not null then we are printing + // so we want to pass back NS_ERROR_ABORT on cancel + if (NS_SUCCEEDED(rv) && aWebBrowserPrint) + { + int32_t status; + aParamBlock->GetInt(0, &status); + return status == 0?NS_ERROR_ABORT:NS_OK; + } + + return rv; +} + +////////////////////////////////////////////////////////////////////// +// nsIWebProgressListener +////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus) +{ + if ((aStateFlags & STATE_STOP) && mWebProgressListener) { + mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); + if (mPrintProgress) { + mPrintProgress->CloseProgressDialog(true); + } + mPrintProgress = nullptr; + mWebProgressListener = nullptr; + } + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress) +{ + if (mWebProgressListener) { + return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); + } + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags) +{ + if (mWebProgressListener) { + return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags); + } + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage) +{ + if (mWebProgressListener) { + return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); + } + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state) +{ + if (mWebProgressListener) { + return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state); + } + return NS_OK; +} diff --git a/embedding/components/printingui/unixshared/nsPrintingPromptService.h b/embedding/components/printingui/unixshared/nsPrintingPromptService.h new file mode 100644 index 000000000..cc0c76929 --- /dev/null +++ b/embedding/components/printingui/unixshared/nsPrintingPromptService.h @@ -0,0 +1,58 @@ +/* -*- 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 "nsPIPromptService.h" +#include "nsIWindowWatcher.h" + +// Printing Progress Includes +#include "nsPrintProgress.h" +#include "nsPrintProgressParams.h" +#include "nsIWebProgressListener.h" + +class nsIDOMWindow; +class nsIDialogParamBlock; + +class nsPrintingPromptService: public nsIPrintingPromptService, + public nsIWebProgressListener +{ + +public: + + nsPrintingPromptService(); + + nsresult Init(); + + NS_DECL_NSIPRINTINGPROMPTSERVICE + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_ISUPPORTS + +protected: + virtual ~nsPrintingPromptService(); + +private: + nsresult DoDialog(mozIDOMWindowProxy *aParent, + nsIDialogParamBlock *aParamBlock, + nsIWebBrowserPrint *aWebBrowserPrint, + nsIPrintSettings* aPS, + const char *aChromeURL); + + nsCOMPtr<nsIWindowWatcher> mWatcher; + nsCOMPtr<nsIPrintProgress> mPrintProgress; + nsCOMPtr<nsIWebProgressListener> mWebProgressListener; +}; + +#endif + diff --git a/embedding/components/printingui/win/moz.build b/embedding/components/printingui/win/moz.build new file mode 100644 index 000000000..fe7b11b2d --- /dev/null +++ b/embedding/components/printingui/win/moz.build @@ -0,0 +1,18 @@ +# -*- 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/. + +UNIFIED_SOURCES += [ + 'nsPrintDialogUtil.cpp', + 'nsPrintingPromptService.cpp', + 'nsPrintProgress.cpp', + 'nsPrintProgressParams.cpp', +] + +EXPORTS += [ + 'nsPrintDialogUtil.h', +] + +FINAL_LIBRARY = 'xul' diff --git a/embedding/components/printingui/win/nsPrintDialogUtil.cpp b/embedding/components/printingui/win/nsPrintDialogUtil.cpp new file mode 100644 index 000000000..896c58e85 --- /dev/null +++ b/embedding/components/printingui/win/nsPrintDialogUtil.cpp @@ -0,0 +1,854 @@ +/* -*- 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/. */ + +/* ------------------------------------------------------------------- +To Build This: + + You need to add this to the the makefile.win in mozilla/dom/base: + + .\$(OBJDIR)\nsFlyOwnPrintDialog.obj \ + + + And this to the makefile.win in mozilla/content/build: + +WIN_LIBS= \ + winspool.lib \ + comctl32.lib \ + comdlg32.lib + +---------------------------------------------------------------------- */ + +#include "plstr.h" +#include <windows.h> +#include <tchar.h> + +#include <unknwn.h> +#include <commdlg.h> + +#include "nsIWebBrowserPrint.h" +#include "nsString.h" +#include "nsIServiceManager.h" +#include "nsReadableUtils.h" +#include "nsIPrintSettings.h" +#include "nsIPrintSettingsWin.h" +#include "nsIPrinterEnumerator.h" + +#include "nsRect.h" + +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" + +#include "nsCRT.h" +#include "prenv.h" /* for PR_GetEnv */ + +#include <windows.h> +#include <winspool.h> + +// For Localization +#include "nsIStringBundle.h" + +// For NS_CopyUnicodeToNative +#include "nsNativeCharsetUtils.h" + +// This is for extending the dialog +#include <dlgs.h> + +#include "nsWindowsHelpers.h" +#include "WinUtils.h" + +// Default labels for the radio buttons +static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen"; +static const char* kTheSelectedFrameStr = "The selected &frame"; +static const char* kEachFrameSeparately = "&Each frame separately"; + + +//----------------------------------------------- +// Global Data +//----------------------------------------------- +// Identifies which new radio btn was cliked on +static UINT gFrameSelectedRadioBtn = 0; + +// Indicates whether the native print dialog was successfully extended +static bool gDialogWasExtended = false; + +#define PRINTDLG_PROPERTIES "chrome://global/locale/printdialog.properties" + +static HWND gParentWnd = nullptr; + +//---------------------------------------------------------------------------------- +// Return localized bundle for resource strings +static nsresult +GetLocalizedBundle(const char * aPropFileName, nsIStringBundle** aStrBundle) +{ + NS_ENSURE_ARG_POINTER(aPropFileName); + NS_ENSURE_ARG_POINTER(aStrBundle); + + nsresult rv; + nsCOMPtr<nsIStringBundle> bundle; + + + // Create bundle + nsCOMPtr<nsIStringBundleService> stringService = + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv) && stringService) { + rv = stringService->CreateBundle(aPropFileName, aStrBundle); + } + + return rv; +} + +//-------------------------------------------------------- +// Return localized string +static nsresult +GetLocalizedString(nsIStringBundle* aStrBundle, const char* aKey, nsString& oVal) +{ + NS_ENSURE_ARG_POINTER(aStrBundle); + NS_ENSURE_ARG_POINTER(aKey); + + // Determine default label from string bundle + nsXPIDLString valUni; + nsAutoString key; + key.AssignWithConversion(aKey); + nsresult rv = aStrBundle->GetStringFromName(key.get(), getter_Copies(valUni)); + if (NS_SUCCEEDED(rv) && valUni) { + oVal.Assign(valUni); + } else { + oVal.Truncate(); + } + return rv; +} + +//-------------------------------------------------------- +// Set a multi-byte string in the control +static void SetTextOnWnd(HWND aControl, const nsString& aStr) +{ + nsAutoCString text; + if (NS_SUCCEEDED(NS_CopyUnicodeToNative(aStr, text))) { + ::SetWindowText(aControl, text.get()); + } +} + +//-------------------------------------------------------- +// Will get the control and localized string by "key" +static void SetText(HWND aParent, + UINT aId, + nsIStringBundle* aStrBundle, + const char* aKey) +{ + HWND wnd = GetDlgItem (aParent, aId); + if (!wnd) { + return; + } + nsAutoString str; + nsresult rv = GetLocalizedString(aStrBundle, aKey, str); + if (NS_SUCCEEDED(rv)) { + SetTextOnWnd(wnd, str); + } +} + +//-------------------------------------------------------- +static void SetRadio(HWND aParent, + UINT aId, + bool aIsSet, + bool isEnabled = true) +{ + HWND wnd = ::GetDlgItem (aParent, aId); + if (!wnd) { + return; + } + if (!isEnabled) { + ::EnableWindow(wnd, FALSE); + return; + } + ::EnableWindow(wnd, TRUE); + ::SendMessage(wnd, BM_SETCHECK, (WPARAM)aIsSet, (LPARAM)0); +} + +//-------------------------------------------------------- +static void SetRadioOfGroup(HWND aDlg, int aRadId) +{ + int radioIds[] = {rad4, rad5, rad6}; + int numRads = 3; + + for (int i=0;i<numRads;i++) { + HWND radWnd = ::GetDlgItem(aDlg, radioIds[i]); + if (radWnd != nullptr) { + ::SendMessage(radWnd, BM_SETCHECK, (WPARAM)(radioIds[i] == aRadId), (LPARAM)0); + } + } +} + +//-------------------------------------------------------- +typedef struct { + const char * mKeyStr; + long mKeyId; +} PropKeyInfo; + +// These are the control ids used in the dialog and +// defined by MS-Windows in commdlg.h +static PropKeyInfo gAllPropKeys[] = { + {"printFramesTitleWindows", grp3}, + {"asLaidOutWindows", rad4}, + {"selectedFrameWindows", rad5}, + {"separateFramesWindows", rad6}, + {nullptr, 0}}; + +//-------------------------------------------------------- +//-------------------------------------------------------- +//-------------------------------------------------------- +//-------------------------------------------------------- +// Get the absolute coords of the child windows relative +// to its parent window +static void GetLocalRect(HWND aWnd, RECT& aRect, HWND aParent) +{ + ::GetWindowRect(aWnd, &aRect); + + // MapWindowPoints converts screen coordinates to client coordinates. + // It works correctly in both left-to-right and right-to-left windows. + ::MapWindowPoints(nullptr, aParent, (LPPOINT)&aRect, 2); +} + +//-------------------------------------------------------- +// Show or Hide the control +static void Show(HWND aWnd, bool bState) +{ + if (aWnd) { + ::ShowWindow(aWnd, bState?SW_SHOW:SW_HIDE); + } +} + +//-------------------------------------------------------- +// Create a child window "control" +static HWND CreateControl(LPCTSTR aType, + DWORD aStyle, + HINSTANCE aHInst, + HWND aHdlg, + int aId, + const nsAString& aStr, + const nsIntRect& aRect) +{ + nsAutoCString str; + if (NS_FAILED(NS_CopyUnicodeToNative(aStr, str))) + return nullptr; + + HWND hWnd = ::CreateWindow (aType, str.get(), + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle, + aRect.x, aRect.y, aRect.width, aRect.height, + (HWND)aHdlg, (HMENU)(intptr_t)aId, + aHInst, nullptr); + if (hWnd == nullptr) return nullptr; + + // get the native font for the dialog and + // set it into the new control + HFONT hFont = (HFONT)::SendMessage(aHdlg, WM_GETFONT, (WPARAM)0, (LPARAM)0); + if (hFont != nullptr) { + ::SendMessage(hWnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0); + } + return hWnd; +} + +//-------------------------------------------------------- +// Create a Radio Button +static HWND CreateRadioBtn(HINSTANCE aHInst, + HWND aHdlg, + int aId, + const char* aStr, + const nsIntRect& aRect) +{ + nsString cStr; + cStr.AssignWithConversion(aStr); + return CreateControl("BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, cStr, aRect); +} + +//-------------------------------------------------------- +// Create a Group Box +static HWND CreateGroupBox(HINSTANCE aHInst, + HWND aHdlg, + int aId, + const nsAString& aStr, + const nsIntRect& aRect) +{ + return CreateControl("BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect); +} + +//-------------------------------------------------------- +// Localizes and initializes the radio buttons and group +static void InitializeExtendedDialog(HWND hdlg, int16_t aHowToEnableFrameUI) +{ + MOZ_ASSERT(aHowToEnableFrameUI != nsIPrintSettings::kFrameEnableNone, + "should not be called"); + + // Localize the new controls in the print dialog + nsCOMPtr<nsIStringBundle> strBundle; + if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) { + int32_t i = 0; + while (gAllPropKeys[i].mKeyStr != nullptr) { + SetText(hdlg, gAllPropKeys[i].mKeyId, strBundle, gAllPropKeys[i].mKeyStr); + i++; + } + } + + // Set up radio buttons + if (aHowToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) { + SetRadio(hdlg, rad4, false); + SetRadio(hdlg, rad5, true); + SetRadio(hdlg, rad6, false); + // set default so user doesn't have to actually press on it + gFrameSelectedRadioBtn = rad5; + + } else { // nsIPrintSettings::kFrameEnableAsIsAndEach + SetRadio(hdlg, rad4, false); + SetRadio(hdlg, rad5, false, false); + SetRadio(hdlg, rad6, true); + // set default so user doesn't have to actually press on it + gFrameSelectedRadioBtn = rad6; + } +} + + +//-------------------------------------------------------- +// Special Hook Procedure for handling the print dialog messages +static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + + if (uiMsg == WM_COMMAND) { + UINT id = LOWORD(wParam); + if (id == rad4 || id == rad5 || id == rad6) { + gFrameSelectedRadioBtn = id; + SetRadioOfGroup(hdlg, id); + } + + } else if (uiMsg == WM_INITDIALOG) { + PRINTDLG * printDlg = (PRINTDLG *)lParam; + if (printDlg == nullptr) return 0L; + + int16_t howToEnableFrameUI = (int16_t)printDlg->lCustData; + // don't add frame options if they would be disabled anyway + // because there are no frames + if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableNone) + return TRUE; + + HINSTANCE hInst = (HINSTANCE)::GetWindowLongPtr(hdlg, GWLP_HINSTANCE); + if (hInst == nullptr) return 0L; + + // Start by getting the local rects of several of the controls + // so we can calculate where the new controls are + HWND wnd = ::GetDlgItem(hdlg, grp1); + if (wnd == nullptr) return 0L; + RECT dlgRect; + GetLocalRect(wnd, dlgRect, hdlg); + + wnd = ::GetDlgItem(hdlg, rad1); // this is the top control "All" + if (wnd == nullptr) return 0L; + RECT rad1Rect; + GetLocalRect(wnd, rad1Rect, hdlg); + + wnd = ::GetDlgItem(hdlg, rad2); // this is the bottom control "Selection" + if (wnd == nullptr) return 0L; + RECT rad2Rect; + GetLocalRect(wnd, rad2Rect, hdlg); + + wnd = ::GetDlgItem(hdlg, rad3); // this is the middle control "Pages" + if (wnd == nullptr) return 0L; + RECT rad3Rect; + GetLocalRect(wnd, rad3Rect, hdlg); + + HWND okWnd = ::GetDlgItem(hdlg, IDOK); + if (okWnd == nullptr) return 0L; + RECT okRect; + GetLocalRect(okWnd, okRect, hdlg); + + wnd = ::GetDlgItem(hdlg, grp4); // this is the "Print range" groupbox + if (wnd == nullptr) return 0L; + RECT prtRect; + GetLocalRect(wnd, prtRect, hdlg); + + + // calculate various different "gaps" for layout purposes + + int rbGap = rad3Rect.top - rad1Rect.bottom; // gap between radiobtns + int grpBotGap = dlgRect.bottom - rad2Rect.bottom; // gap from bottom rb to bottom of grpbox + int grpGap = dlgRect.top - prtRect.bottom ; // gap between group boxes + int top = dlgRect.bottom + grpGap; + int radHgt = rad1Rect.bottom - rad1Rect.top + 1; // top of new group box + int y = top+(rad1Rect.top-dlgRect.top); // starting pos of first radio + int rbWidth = dlgRect.right - rad1Rect.left - 5; // measure from rb left to the edge of the groupbox + // (5 is arbitrary) + nsIntRect rect; + + // Create and position the radio buttons + // + // If any one control cannot be created then + // hide the others and bail out + // + rect.SetRect(rad1Rect.left, y, rbWidth,radHgt); + HWND rad4Wnd = CreateRadioBtn(hInst, hdlg, rad4, kAsLaidOutOnScreenStr, rect); + if (rad4Wnd == nullptr) return 0L; + y += radHgt + rbGap; + + rect.SetRect(rad1Rect.left, y, rbWidth, radHgt); + HWND rad5Wnd = CreateRadioBtn(hInst, hdlg, rad5, kTheSelectedFrameStr, rect); + if (rad5Wnd == nullptr) { + Show(rad4Wnd, FALSE); // hide + return 0L; + } + y += radHgt + rbGap; + + rect.SetRect(rad1Rect.left, y, rbWidth, radHgt); + HWND rad6Wnd = CreateRadioBtn(hInst, hdlg, rad6, kEachFrameSeparately, rect); + if (rad6Wnd == nullptr) { + Show(rad4Wnd, FALSE); // hide + Show(rad5Wnd, FALSE); // hide + return 0L; + } + y += radHgt + grpBotGap; + + // Create and position the group box + rect.SetRect (dlgRect.left, top, dlgRect.right-dlgRect.left+1, y-top+1); + HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, NS_LITERAL_STRING("Print Frame"), rect); + if (grpBoxWnd == nullptr) { + Show(rad4Wnd, FALSE); // hide + Show(rad5Wnd, FALSE); // hide + Show(rad6Wnd, FALSE); // hide + return 0L; + } + + // Here we figure out the old height of the dlg + // then figure its gap from the old grpbx to the bottom + // then size the dlg + RECT pr, cr; + ::GetWindowRect(hdlg, &pr); + ::GetClientRect(hdlg, &cr); + + int dlgHgt = (cr.bottom - cr.top) + 1; + int bottomGap = dlgHgt - okRect.bottom; + pr.bottom += (dlgRect.bottom-dlgRect.top) + grpGap + 1 - (dlgHgt-dlgRect.bottom) + bottomGap; + + ::SetWindowPos(hdlg, nullptr, pr.left, pr.top, pr.right-pr.left+1, pr.bottom-pr.top+1, + SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER); + + // figure out the new height of the dialog + ::GetClientRect(hdlg, &cr); + dlgHgt = (cr.bottom - cr.top) + 1; + + // Reposition the OK and Cancel btns + int okHgt = okRect.bottom - okRect.top + 1; + ::SetWindowPos(okWnd, nullptr, okRect.left, dlgHgt-bottomGap-okHgt, 0, 0, + SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER); + + HWND cancelWnd = ::GetDlgItem(hdlg, IDCANCEL); + if (cancelWnd == nullptr) return 0L; + + RECT cancelRect; + GetLocalRect(cancelWnd, cancelRect, hdlg); + int cancelHgt = cancelRect.bottom - cancelRect.top + 1; + ::SetWindowPos(cancelWnd, nullptr, cancelRect.left, dlgHgt-bottomGap-cancelHgt, 0, 0, + SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER); + + // localize and initialize the groupbox and radiobuttons + InitializeExtendedDialog(hdlg, howToEnableFrameUI); + + // Looks like we were able to extend the dialog + gDialogWasExtended = true; + return TRUE; + } + return 0L; +} + +//---------------------------------------------------------------------------------- +// Returns a Global Moveable Memory Handle to a DevMode +// from the Printer by the name of aPrintName +// +// NOTE: +// This function assumes that aPrintName has already been converted from +// unicode +// +static nsReturnRef<nsHGLOBAL> +CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, + nsIPrintSettings* aPS) +{ + nsHPRINTER hPrinter = nullptr; + // const cast kludge for silly Win32 api's + LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get())); + BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr); + if (!status) { + return nsReturnRef<nsHGLOBAL>(); + } + + // Make sure hPrinter is closed on all paths + nsAutoPrinter autoPrinter(hPrinter); + + // Get the buffer size + LONG needed = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr, + nullptr, 0); + if (needed < 0) { + return nsReturnRef<nsHGLOBAL>(); + } + + // Allocate a buffer of the correct size. + nsAutoDevMode newDevMode((LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, + needed)); + if (!newDevMode) { + return nsReturnRef<nsHGLOBAL>(); + } + + nsHGLOBAL hDevMode = ::GlobalAlloc(GHND, needed); + nsAutoGlobalMem globalDevMode(hDevMode); + if (!hDevMode) { + return nsReturnRef<nsHGLOBAL>(); + } + + LONG ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, newDevMode, + nullptr, DM_OUT_BUFFER); + if (ret != IDOK) { + return nsReturnRef<nsHGLOBAL>(); + } + + // Lock memory and copy contents from DEVMODE (current printer) + // to Global Memory DEVMODE + LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hDevMode); + if (!devMode) { + return nsReturnRef<nsHGLOBAL>(); + } + + memcpy(devMode, newDevMode.get(), needed); + // Initialize values from the PrintSettings + nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS); + MOZ_ASSERT(psWin); + psWin->CopyToNative(devMode); + + // Sets back the changes we made to the DevMode into the Printer Driver + ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode, + DM_IN_BUFFER | DM_OUT_BUFFER); + if (ret != IDOK) { + ::GlobalUnlock(hDevMode); + return nsReturnRef<nsHGLOBAL>(); + } + + ::GlobalUnlock(hDevMode); + + return globalDevMode.out(); +} + +//------------------------------------------------------------------ +// helper +static void GetDefaultPrinterNameFromGlobalPrinters(nsXPIDLString &printerName) +{ + nsCOMPtr<nsIPrinterEnumerator> prtEnum = do_GetService("@mozilla.org/gfx/printerenumerator;1"); + if (prtEnum) { + prtEnum->GetDefaultPrinterName(getter_Copies(printerName)); + } +} + +// Determine whether we have a completely native dialog +// or whether we cshould extend it +static bool ShouldExtendPrintDialog() +{ + nsresult rv; + nsCOMPtr<nsIPrefService> prefs = + do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, true); + nsCOMPtr<nsIPrefBranch> prefBranch; + rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch)); + NS_ENSURE_SUCCESS(rv, true); + + bool result; + rv = prefBranch->GetBoolPref("print.extend_native_print_dialog", &result); + NS_ENSURE_SUCCESS(rv, true); + return result; +} + +//------------------------------------------------------------------ +// Displays the native Print Dialog +static nsresult +ShowNativePrintDialog(HWND aHWnd, + nsIPrintSettings* aPrintSettings) +{ + //NS_ENSURE_ARG_POINTER(aHWnd); + NS_ENSURE_ARG_POINTER(aPrintSettings); + + gDialogWasExtended = false; + + // Get the Print Name to be used + nsXPIDLString printerName; + aPrintSettings->GetPrinterName(getter_Copies(printerName)); + + // If there is no name then use the default printer + if (printerName.IsEmpty()) { + GetDefaultPrinterNameFromGlobalPrinters(printerName); + } else { + HANDLE hPrinter = nullptr; + if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())), + &hPrinter, nullptr)) { + // If the last used printer is not found, we should use default printer. + GetDefaultPrinterNameFromGlobalPrinters(printerName); + } else { + ::ClosePrinter(hPrinter); + } + } + + // Now create a DEVNAMES struct so the the dialog is initialized correctly. + + uint32_t len = printerName.Length(); + nsHGLOBAL hDevNames = ::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1) + + sizeof(DEVNAMES)); + nsAutoGlobalMem autoDevNames(hDevNames); + if (!hDevNames) { + return NS_ERROR_OUT_OF_MEMORY; + } + + DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames); + if (!pDevNames) { + return NS_ERROR_FAILURE; + } + pDevNames->wDriverOffset = sizeof(DEVNAMES)/sizeof(wchar_t); + pDevNames->wDeviceOffset = sizeof(DEVNAMES)/sizeof(wchar_t); + pDevNames->wOutputOffset = sizeof(DEVNAMES)/sizeof(wchar_t)+len; + pDevNames->wDefault = 0; + + memcpy(pDevNames+1, printerName, (len + 1) * sizeof(wchar_t)); + ::GlobalUnlock(hDevNames); + + // Create a Moveable Memory Object that holds a new DevMode + // from the Printer Name + // The PRINTDLG.hDevMode requires that it be a moveable memory object + // NOTE: autoDevMode is automatically freed when any error occurred + nsAutoGlobalMem autoDevMode(CreateGlobalDevModeAndInit(printerName, aPrintSettings)); + + // Prepare to Display the Print Dialog + PRINTDLGW prntdlg; + memset(&prntdlg, 0, sizeof(PRINTDLGW)); + + prntdlg.lStructSize = sizeof(prntdlg); + prntdlg.hwndOwner = aHWnd; + prntdlg.hDevMode = autoDevMode.get(); + prntdlg.hDevNames = hDevNames; + prntdlg.hDC = nullptr; + prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC | + PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE; + + // if there is a current selection then enable the "Selection" radio button + int16_t howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone; + bool isOn; + aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn); + if (!isOn) { + prntdlg.Flags |= PD_NOSELECTION; + } + aPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI); + + int32_t pg = 1; + aPrintSettings->GetStartPageRange(&pg); + prntdlg.nFromPage = pg; + + aPrintSettings->GetEndPageRange(&pg); + prntdlg.nToPage = pg; + + prntdlg.nMinPage = 1; + prntdlg.nMaxPage = 0xFFFF; + prntdlg.nCopies = 1; + prntdlg.lpfnSetupHook = nullptr; + prntdlg.lpSetupTemplateName = nullptr; + prntdlg.hPrintTemplate = nullptr; + prntdlg.hSetupTemplate = nullptr; + + prntdlg.hInstance = nullptr; + prntdlg.lpPrintTemplateName = nullptr; + + if (!ShouldExtendPrintDialog()) { + prntdlg.lCustData = 0; + prntdlg.lpfnPrintHook = nullptr; + } else { + // Set up print dialog "hook" procedure for extending the dialog + prntdlg.lCustData = (DWORD)howToEnableFrameUI; + prntdlg.lpfnPrintHook = (LPPRINTHOOKPROC)PrintHookProc; + prntdlg.Flags |= PD_ENABLEPRINTHOOK; + } + + BOOL result; + { + mozilla::widget::WinUtils::AutoSystemDpiAware dpiAwareness; + result = ::PrintDlgW(&prntdlg); + } + + if (TRUE == result) { + // check to make sure we don't have any nullptr pointers + NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE); + + if (prntdlg.hDevNames == nullptr) { + return NS_ERROR_FAILURE; + } + // Lock the deviceNames and check for nullptr + DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames); + if (devnames == nullptr) { + return NS_ERROR_FAILURE; + } + + char16_t* device = &(((char16_t *)devnames)[devnames->wDeviceOffset]); + char16_t* driver = &(((char16_t *)devnames)[devnames->wDriverOffset]); + + // Check to see if the "Print To File" control is checked + // then take the name from devNames and set it in the PrintSettings + // + // NOTE: + // As per Microsoft SDK documentation the returned value offset from + // devnames->wOutputOffset is either "FILE:" or nullptr + // if the "Print To File" checkbox is checked it MUST be "FILE:" + // We assert as an extra safety check. + if (prntdlg.Flags & PD_PRINTTOFILE) { + char16ptr_t fileName = &(((wchar_t *)devnames)[devnames->wOutputOffset]); + NS_ASSERTION(wcscmp(fileName, L"FILE:") == 0, "FileName must be `FILE:`"); + aPrintSettings->SetToFileName(fileName); + aPrintSettings->SetPrintToFile(true); + } else { + // clear "print to file" info + aPrintSettings->SetPrintToFile(false); + aPrintSettings->SetToFileName(nullptr); + } + + nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings)); + if (!psWin) { + return NS_ERROR_FAILURE; + } + + // Setup local Data members + psWin->SetDeviceName(device); + psWin->SetDriverName(driver); + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + wprintf(L"printer: driver %s, device %s flags: %d\n", driver, device, prntdlg.Flags); +#endif + // fill the print options with the info from the dialog + + aPrintSettings->SetPrinterName(device); + + if (prntdlg.Flags & PD_SELECTION) { + aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection); + + } else if (prntdlg.Flags & PD_PAGENUMS) { + aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange); + aPrintSettings->SetStartPageRange(prntdlg.nFromPage); + aPrintSettings->SetEndPageRange(prntdlg.nToPage); + + } else { // (prntdlg.Flags & PD_ALLPAGES) + aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages); + } + + if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) { + // make sure the dialog got extended + if (gDialogWasExtended) { + // check to see about the frame radio buttons + switch (gFrameSelectedRadioBtn) { + case rad4: + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs); + break; + case rad5: + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame); + break; + case rad6: + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep); + break; + } // switch + } else { + // if it didn't get extended then have it default to printing + // each frame separately + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep); + } + } else { + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames); + } + // Unlock DeviceNames + ::GlobalUnlock(prntdlg.hDevNames); + + // Transfer the settings from the native data to the PrintSettings + LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode); + if (!devMode || !prntdlg.hDC) { + return NS_ERROR_FAILURE; + } + psWin->SetDevMode(devMode); // copies DevMode + psWin->CopyFromNative(prntdlg.hDC, devMode); + ::GlobalUnlock(prntdlg.hDevMode); + ::DeleteDC(prntdlg.hDC); + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + bool printSelection = prntdlg.Flags & PD_SELECTION; + bool printAllPages = prntdlg.Flags & PD_ALLPAGES; + bool printNumPages = prntdlg.Flags & PD_PAGENUMS; + int32_t fromPageNum = 0; + int32_t toPageNum = 0; + + if (printNumPages) { + fromPageNum = prntdlg.nFromPage; + toPageNum = prntdlg.nToPage; + } + if (printSelection) { + printf("Printing the selection\n"); + + } else if (printAllPages) { + printf("Printing all the pages\n"); + + } else { + printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum); + } +#endif + + } else { + ::SetFocus(aHWnd); + aPrintSettings->SetIsCancelled(true); + return NS_ERROR_ABORT; + } + + return NS_OK; +} + +//------------------------------------------------------------------ +static void +PrepareForPrintDialog(nsIWebBrowserPrint* aWebBrowserPrint, nsIPrintSettings* aPS) +{ + NS_ASSERTION(aWebBrowserPrint, "Can't be null"); + NS_ASSERTION(aPS, "Can't be null"); + + bool isFramesetDocument; + bool isFramesetFrameSelected; + bool isIFrameSelected; + bool isRangeSelection; + + aWebBrowserPrint->GetIsFramesetDocument(&isFramesetDocument); + aWebBrowserPrint->GetIsFramesetFrameSelected(&isFramesetFrameSelected); + aWebBrowserPrint->GetIsIFrameSelected(&isIFrameSelected); + aWebBrowserPrint->GetIsRangeSelection(&isRangeSelection); + + // Setup print options for UI + if (isFramesetDocument) { + if (isFramesetFrameSelected) { + aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll); + } else { + aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach); + } + } else { + aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone); + } + + // Now determine how to set up the Frame print UI + aPS->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, isRangeSelection || isIFrameSelected); + +} + +//---------------------------------------------------------------------------------- +//-- Show Print Dialog +//---------------------------------------------------------------------------------- +nsresult NativeShowPrintDialog(HWND aHWnd, + nsIWebBrowserPrint* aWebBrowserPrint, + nsIPrintSettings* aPrintSettings) +{ + PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings); + + nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings); + if (aHWnd) { + ::DestroyWindow(aHWnd); + } + + return rv; +} + diff --git a/embedding/components/printingui/win/nsPrintDialogUtil.h b/embedding/components/printingui/win/nsPrintDialogUtil.h new file mode 100644 index 000000000..ada3da239 --- /dev/null +++ b/embedding/components/printingui/win/nsPrintDialogUtil.h @@ -0,0 +1,12 @@ +/* -*- 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 nsFlyOwnDialog_h___ +#define nsFlyOwnDialog_h___ + +nsresult NativeShowPrintDialog(HWND aHWnd, + nsIWebBrowserPrint* aWebBrowserPrint, + nsIPrintSettings* aPrintSettings); + +#endif /* nsFlyOwnDialog_h___ */ diff --git a/embedding/components/printingui/win/nsPrintProgress.cpp b/embedding/components/printingui/win/nsPrintProgress.cpp new file mode 100644 index 000000000..0b1c10a2c --- /dev/null +++ b/embedding/components/printingui/win/nsPrintProgress.cpp @@ -0,0 +1,293 @@ +/* -*- 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 "nsArray.h" +#include "nsIBaseWindow.h" +#include "nsIDocShell.h" +#include "nsIDocShellTreeOwner.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIXULWindow.h" +#include "nsXPCOM.h" +#include "nsISupportsPrimitives.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsPIDOMWindow.h" + +#if 0 +NS_IMPL_ADDREF(nsPrintProgress) +NS_IMPL_RELEASE(nsPrintProgress) +#else +NS_IMETHODIMP_(MozExternalRefCountType) nsPrintProgress::AddRef(void) +{ + NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt"); + nsrefcnt count; + count = ++mRefCnt; + //NS_LOG_ADDREF(this, count, "nsPrintProgress", sizeof(*this)); + return count; +} + +NS_IMETHODIMP_(MozExternalRefCountType) nsPrintProgress::Release(void) +{ + nsrefcnt count; + NS_PRECONDITION(0 != mRefCnt, "dup release"); + count = --mRefCnt; + //NS_LOG_RELEASE(this, count, "nsPrintProgress"); + if (0 == count) { + mRefCnt = 1; /* stabilize */ + /* enable this to find non-threadsafe destructors: */ + /* NS_ASSERT_OWNINGTHREAD(nsPrintProgress); */ + delete this; + return 0; + } + return count; +} + +#endif + +NS_INTERFACE_MAP_BEGIN(nsPrintProgress) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback) + NS_INTERFACE_MAP_ENTRY(nsIPrintProgress) + NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) +NS_INTERFACE_MAP_END_THREADSAFE + + +nsPrintProgress::nsPrintProgress() +{ + m_closeProgress = false; + m_processCanceled = false; + m_pendingStateFlags = -1; + m_pendingStateValue = NS_OK; +} + +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, /*weak =*/ false); + + array->AppendElement(parameters, /*weak = */ false); + + // 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<nsIXULWindow> ownerXULWindow = do_GetInterface(owner); + nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerXULWindow); + NS_ENSURE_STATE(ownerWindow); + + nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = nsPIDOMWindowOuter::From(ownerWindow); + + // Open the dialog. + nsCOMPtr<nsPIDOMWindowOuter> newWindow; + rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL), + NS_LITERAL_STRING("_blank"), + NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"), + array, getter_AddRefs(newWindow)); + } + + return rv; +} + +NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose) +{ + m_closeProgress = true; + // XXX Casting from bool to nsresult + return OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, + static_cast<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) +{ + 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) +{ + 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) +{ + 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_OK; +} + +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 state) +{ + return NS_OK; +} + +nsresult nsPrintProgress::ReleaseListeners() +{ + m_listenerList.Clear(); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status) +{ + return OnStatusChange(nullptr, nullptr, NS_OK, status); +} + +NS_IMETHODIMP nsPrintProgress::StartMeteors() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::StopMeteors() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell, mozIDOMWindowProxy *window) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsPrintProgress::CloseWindow() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/embedding/components/printingui/win/nsPrintProgress.h b/embedding/components/printingui/win/nsPrintProgress.h new file mode 100644 index 000000000..adc5a14cc --- /dev/null +++ b/embedding/components/printingui/win/nsPrintProgress.h @@ -0,0 +1,43 @@ +/* -*- 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 "nsIDOMWindow.h" +#include "nsIPrintStatusFeedback.h" +#include "nsString.h" +#include "nsIWindowWatcher.h" +#include "nsIObserver.h" + +class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIPRINTPROGRESS + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSIPRINTSTATUSFEEDBACK + + nsPrintProgress(); + 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; +}; + +#endif diff --git a/embedding/components/printingui/win/nsPrintProgressParams.cpp b/embedding/components/printingui/win/nsPrintProgressParams.cpp new file mode 100644 index 000000000..eba86b298 --- /dev/null +++ b/embedding/components/printingui/win/nsPrintProgressParams.cpp @@ -0,0 +1,47 @@ +/* -*- 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() +{ +} + +nsPrintProgressParams::~nsPrintProgressParams() +{ +} + +NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle) +{ + NS_ENSURE_ARG(aDocTitle); + + *aDocTitle = ToNewUnicode(mDocTitle); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle) +{ + mDocTitle = aDocTitle; + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL) +{ + NS_ENSURE_ARG(aDocURL); + + *aDocURL = ToNewUnicode(mDocURL); + return NS_OK; +} + +NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL) +{ + mDocURL = aDocURL; + return NS_OK; +} + diff --git a/embedding/components/printingui/win/nsPrintProgressParams.h b/embedding/components/printingui/win/nsPrintProgressParams.h new file mode 100644 index 000000000..aebfbff7f --- /dev/null +++ b/embedding/components/printingui/win/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 +{ + virtual ~nsPrintProgressParams(); + +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTPROGRESSPARAMS + + nsPrintProgressParams(); + +private: + nsString mDocTitle; + nsString mDocURL; +}; + +#endif diff --git a/embedding/components/printingui/win/nsPrintingPromptService.cpp b/embedding/components/printingui/win/nsPrintingPromptService.cpp new file mode 100644 index 000000000..83727ee4e --- /dev/null +++ b/embedding/components/printingui/win/nsPrintingPromptService.cpp @@ -0,0 +1,341 @@ +/* -*- 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 "nsCOMPtr.h" + +#include "nsPrintingPromptService.h" +#include "nsIPrintingPromptService.h" +#include "nsIFactory.h" +#include "nsPIDOMWindow.h" +#include "nsReadableUtils.h" +#include "nsIEmbeddingSiteWindow.h" +#include "nsIServiceManager.h" +#include "nsIWebBrowserChrome.h" +#include "nsIWindowWatcher.h" +#include "nsPrintDialogUtil.h" + +// Printing Progress Includes +#include "nsPrintProgress.h" +#include "nsPrintProgressParams.h" +#include "nsIWebProgressListener.h" + +// XP Dialog includes +#include "nsArray.h" +#include "nsIDialogParamBlock.h" +#include "nsISupportsUtils.h" + +// Includes need to locate the native Window +#include "nsIWidget.h" +#include "nsIBaseWindow.h" +#include "nsIWebBrowserChrome.h" +#include "nsIDocShellTreeOwner.h" +#include "nsIDocShellTreeItem.h" +#include "nsIDocShell.h" +#include "nsIInterfaceRequestorUtils.h" + + +static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul"; +static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul"; +static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul"; + +/**************************************************************** + ************************* ParamBlock *************************** + ****************************************************************/ + +class ParamBlock { + +public: + ParamBlock() + { + mBlock = 0; + } + ~ParamBlock() + { + NS_IF_RELEASE(mBlock); + } + nsresult Init() { + return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock); + } + nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; } + operator nsIDialogParamBlock * const () { return mBlock; } + +private: + nsIDialogParamBlock *mBlock; +}; + +//***************************************************************************** + +NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener) + +nsPrintingPromptService::nsPrintingPromptService() +{ +} + +//----------------------------------------------------------- +nsPrintingPromptService::~nsPrintingPromptService() +{ +} + +//----------------------------------------------------------- +nsresult +nsPrintingPromptService::Init() +{ + nsresult rv; + mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); + return rv; +} + +//----------------------------------------------------------- +HWND +nsPrintingPromptService::GetHWNDForDOMWindow(mozIDOMWindowProxy *aWindow) +{ + nsCOMPtr<nsIWebBrowserChrome> chrome; + + // We might be embedded so check this path first + if (mWatcher) { + nsCOMPtr<mozIDOMWindowProxy> fosterParent; + if (!aWindow) + { // it will be a dependent window. try to find a foster parent. + mWatcher->GetActiveWindow(getter_AddRefs(fosterParent)); + aWindow = fosterParent; + } + mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome)); + } + + if (chrome) { + nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome)); + if (site) + { + HWND w; + site->GetSiteWindow(reinterpret_cast<void **>(&w)); + return w; + } + } + + // Now we might be the Browser so check this path + nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow); + + nsCOMPtr<nsIDocShellTreeItem> treeItem = + do_QueryInterface(window->GetDocShell()); + if (!treeItem) return nullptr; + + nsCOMPtr<nsIDocShellTreeOwner> treeOwner; + treeItem->GetTreeOwner(getter_AddRefs(treeOwner)); + if (!treeOwner) return nullptr; + + nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(treeOwner)); + if (!webBrowserChrome) return nullptr; + + nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webBrowserChrome)); + if (!baseWin) return nullptr; + + nsCOMPtr<nsIWidget> widget; + baseWin->GetMainWidget(getter_AddRefs(widget)); + if (!widget) return nullptr; + + return (HWND)widget->GetNativeData(NS_NATIVE_TMP_WINDOW); + +} + + +/////////////////////////////////////////////////////////////////////////////// +// nsIPrintingPromptService + +//----------------------------------------------------------- +NS_IMETHODIMP +nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings) +{ + NS_ENSURE_ARG(parent); + + HWND hWnd = GetHWNDForDOMWindow(parent); + NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!"); + + return NativeShowPrintDialog(hWnd, webBrowserPrint, printSettings); +} + + +NS_IMETHODIMP +nsPrintingPromptService::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(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(); + 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; +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs) +{ + NS_ENSURE_ARG(printSettings); + + ParamBlock block; + nsresult rv = block.Init(); + if (NS_FAILED(rv)) + return rv; + + block->SetInt(0, 0); + rv = DoDialog(parent, block, printSettings, kPageSetupDialogURL); + + // if aWebBrowserPrint is not null then we are printing + // so we want to pass back NS_ERROR_ABORT on cancel + if (NS_SUCCEEDED(rv)) + { + int32_t status; + block->GetInt(0, &status); + return status == 0?NS_ERROR_ABORT:NS_OK; + } + + return rv; +} + +NS_IMETHODIMP +nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +//----------------------------------------------------------- +// Helper to Fly XP Dialog +nsresult +nsPrintingPromptService::DoDialog(mozIDOMWindowProxy *aParent, + nsIDialogParamBlock *aParamBlock, + nsIPrintSettings* aPS, + const char *aChromeURL) +{ + NS_ENSURE_ARG(aParamBlock); + NS_ENSURE_ARG(aPS); + NS_ENSURE_ARG(aChromeURL); + + if (!mWatcher) + return NS_ERROR_FAILURE; + + // get a parent, if at all possible + // (though we'd rather this didn't fail, it's OK if it does. so there's + // no failure or null check.) + nsCOMPtr<mozIDOMWindowProxy> activeParent; // retain ownership for method lifetime + if (!aParent) + { + mWatcher->GetActiveWindow(getter_AddRefs(activeParent)); + aParent = activeParent; + } + + // create a nsIMutableArray of the parameters + // being passed to the window + nsCOMPtr<nsIMutableArray> array = nsArray::Create(); + + nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS)); + NS_ASSERTION(psSupports, "PrintSettings must be a supports"); + array->AppendElement(psSupports, /*weak =*/ false); + + nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock)); + NS_ASSERTION(blkSupps, "IOBlk must be a supports"); + array->AppendElement(blkSupps, /*weak =*/ false); + + nsCOMPtr<mozIDOMWindowProxy> dialog; + nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank", + "centerscreen,chrome,modal,titlebar", array, + getter_AddRefs(dialog)); + + return rv; +} + +////////////////////////////////////////////////////////////////////// +// nsIWebProgressListener +////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus) +{ + if ((aStateFlags & STATE_STOP) && mWebProgressListener) + { + mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); + if (mPrintProgress) + { + mPrintProgress->CloseProgressDialog(true); + } + mPrintProgress = nullptr; + mWebProgressListener = nullptr; + } + return NS_OK; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress) +{ + if (mWebProgressListener) + { + return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags) +{ + if (mWebProgressListener) + { + return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags); + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage) +{ + if (mWebProgressListener) + { + return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state) +{ + if (mWebProgressListener) + { + return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state); + } + return NS_ERROR_FAILURE; +} + + diff --git a/embedding/components/printingui/win/nsPrintingPromptService.h b/embedding/components/printingui/win/nsPrintingPromptService.h new file mode 100644 index 000000000..76bc7a804 --- /dev/null +++ b/embedding/components/printingui/win/nsPrintingPromptService.h @@ -0,0 +1,58 @@ +/* -*- 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 + +#include <windows.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 "nsPIPromptService.h" +#include "nsIWindowWatcher.h" + +// Printing Progress Includes +#include "nsPrintProgress.h" +#include "nsPrintProgressParams.h" +#include "nsIWebProgressListener.h" + +class nsIDOMWindow; +class nsIDialogParamBlock; + +class nsPrintingPromptService: public nsIPrintingPromptService, + public nsIWebProgressListener +{ + virtual ~nsPrintingPromptService(); + +public: + nsPrintingPromptService(); + + nsresult Init(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTINGPROMPTSERVICE + NS_DECL_NSIWEBPROGRESSLISTENER + +private: + HWND GetHWNDForDOMWindow(mozIDOMWindowProxy *parent); + nsresult DoDialog(mozIDOMWindowProxy *aParent, + nsIDialogParamBlock *aParamBlock, + nsIPrintSettings* aPS, + const char *aChromeURL); + + nsCOMPtr<nsIWindowWatcher> mWatcher; + nsCOMPtr<nsIPrintProgress> mPrintProgress; + nsCOMPtr<nsIWebProgressListener> mWebProgressListener; + +}; + +#endif + |