forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			168 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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 "nsPrinterListBase.h"
 | |
| #include "PrintBackgroundTask.h"
 | |
| #include "mozilla/ErrorResult.h"
 | |
| #include "mozilla/gfx/Rect.h"
 | |
| #include "mozilla/IntegerRange.h"
 | |
| #include "mozilla/intl/Localization.h"
 | |
| #include "mozilla/Maybe.h"
 | |
| #include "mozilla/RefPtr.h"
 | |
| #include "xpcpublic.h"
 | |
| 
 | |
| using namespace mozilla;
 | |
| 
 | |
| using mozilla::ErrorResult;
 | |
| using mozilla::intl::Localization;
 | |
| using PrinterInfo = nsPrinterListBase::PrinterInfo;
 | |
| using MarginDouble = mozilla::gfx::MarginDouble;
 | |
| 
 | |
| nsPrinterListBase::nsPrinterListBase() = default;
 | |
| nsPrinterListBase::~nsPrinterListBase() = default;
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTION(nsPrinterListBase, mPrintersPromise)
 | |
| 
 | |
| NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterListBase)
 | |
|   NS_INTERFACE_MAP_ENTRY(nsIPrinterList)
 | |
|   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinterList)
 | |
| NS_INTERFACE_MAP_END
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterListBase)
 | |
| NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterListBase)
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| template <>
 | |
| void ResolveOrReject(dom::Promise& aPromise, nsPrinterListBase& aList,
 | |
|                      const nsTArray<PrinterInfo>& aInfo) {
 | |
|   nsTArray<RefPtr<nsIPrinter>> printers;
 | |
|   printers.SetCapacity(aInfo.Length());
 | |
|   for (auto& info : aInfo) {
 | |
|     printers.AppendElement(aList.CreatePrinter(info));
 | |
|   }
 | |
|   aPromise.MaybeResolve(printers);
 | |
| }
 | |
| 
 | |
| template <>
 | |
| void ResolveOrReject(dom::Promise& aPromise, nsPrinterListBase& aList,
 | |
|                      const Maybe<PrinterInfo>& aInfo) {
 | |
|   if (aInfo) {
 | |
|     aPromise.MaybeResolve(aList.CreatePrinter(aInfo.value()));
 | |
|   } else {
 | |
|     aPromise.MaybeRejectWithNotFoundError("Printer not found");
 | |
|   }
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla
 | |
| 
 | |
| NS_IMETHODIMP nsPrinterListBase::GetPrinters(JSContext* aCx,
 | |
|                                              Promise** aResult) {
 | |
|   EnsureCommonPaperInfo(aCx);
 | |
|   return mozilla::AsyncPromiseAttributeGetter(*this, mPrintersPromise, aCx,
 | |
|                                               aResult, "Printers"_ns,
 | |
|                                               &nsPrinterListBase::Printers);
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP nsPrinterListBase::GetPrinterByName(const nsAString& aPrinterName,
 | |
|                                                   JSContext* aCx,
 | |
|                                                   Promise** aResult) {
 | |
|   EnsureCommonPaperInfo(aCx);
 | |
|   return PrintBackgroundTaskPromise(*this, aCx, aResult, "PrinterByName"_ns,
 | |
|                                     &nsPrinterListBase::PrinterByName,
 | |
|                                     nsString{aPrinterName});
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP nsPrinterListBase::GetPrinterBySystemName(
 | |
|     const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
 | |
|   EnsureCommonPaperInfo(aCx);
 | |
|   return PrintBackgroundTaskPromise(
 | |
|       *this, aCx, aResult, "PrinterBySystemName"_ns,
 | |
|       &nsPrinterListBase::PrinterBySystemName, nsString{aPrinterName});
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP nsPrinterListBase::GetNamedOrDefaultPrinter(
 | |
|     const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
 | |
|   EnsureCommonPaperInfo(aCx);
 | |
|   return PrintBackgroundTaskPromise(
 | |
|       *this, aCx, aResult, "NamedOrDefaultPrinter"_ns,
 | |
|       &nsPrinterListBase::NamedOrDefaultPrinter, nsString{aPrinterName});
 | |
| }
 | |
| 
 | |
| Maybe<PrinterInfo> nsPrinterListBase::NamedOrDefaultPrinter(
 | |
|     nsString aName) const {
 | |
|   if (Maybe<PrinterInfo> value = PrinterByName(std::move(aName))) {
 | |
|     return value;
 | |
|   }
 | |
| 
 | |
|   // Since the name had to be passed by-value, we can re-use it to fetch the
 | |
|   // default printer name, potentially avoiding an extra string allocation.
 | |
|   if (NS_SUCCEEDED(SystemDefaultPrinterName(aName))) {
 | |
|     return PrinterByName(std::move(aName));
 | |
|   }
 | |
| 
 | |
|   return Nothing();
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP nsPrinterListBase::GetFallbackPaperList(JSContext* aCx,
 | |
|                                                       Promise** aResult) {
 | |
|   ErrorResult rv;
 | |
|   nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
 | |
|   RefPtr<Promise> promise = Promise::Create(global, rv);
 | |
|   if (MOZ_UNLIKELY(rv.Failed())) {
 | |
|     *aResult = nullptr;
 | |
|     return rv.StealNSResult();
 | |
|   }
 | |
| 
 | |
|   EnsureCommonPaperInfo(aCx);
 | |
|   nsTArray<RefPtr<nsPaper>> papers;
 | |
|   papers.SetCapacity(nsPaper::kNumCommonPaperSizes);
 | |
|   for (const auto& info : *mCommonPaperInfo) {
 | |
|     papers.AppendElement(MakeRefPtr<nsPaper>(info));
 | |
|   }
 | |
| 
 | |
|   promise->MaybeResolve(papers);
 | |
|   promise.forget(aResult);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| void nsPrinterListBase::EnsureCommonPaperInfo(JSContext* aCx) {
 | |
|   MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
 | |
|   if (mCommonPaperInfo) {
 | |
|     return;
 | |
|   }
 | |
|   RefPtr<CommonPaperInfoArray> localizedPaperInfo =
 | |
|       MakeRefPtr<CommonPaperInfoArray>();
 | |
|   CommonPaperInfoArray& paperArray = *localizedPaperInfo;
 | |
|   // Apply localization to the names while constructing the PaperInfo, if
 | |
|   // available (otherwise leave them as the internal keys, which are at least
 | |
|   // somewhat recognizable).
 | |
|   IgnoredErrorResult rv;
 | |
|   nsTArray<nsCString> resIds = {
 | |
|       "toolkit/printing/printUI.ftl"_ns,
 | |
|   };
 | |
|   RefPtr<Localization> l10n = Localization::Create(resIds, true);
 | |
| 
 | |
|   for (auto i : IntegerRange(nsPaper::kNumCommonPaperSizes)) {
 | |
|     const CommonPaperSize& size = nsPaper::kCommonPaperSizes[i];
 | |
|     PaperInfo& info = paperArray[i];
 | |
| 
 | |
|     nsAutoCString key{"printui-paper-"};
 | |
|     key.Append(size.mLocalizableNameKey);
 | |
|     nsAutoCString name;
 | |
|     l10n->FormatValueSync(key, {}, name, rv);
 | |
| 
 | |
|     // Fill out the info with our PWG size and the localized name.
 | |
|     info.mId = size.mPWGName;
 | |
|     CopyUTF8toUTF16(
 | |
|         (rv.Failed() || name.IsEmpty())
 | |
|             ? static_cast<const nsCString&>(size.mLocalizableNameKey)
 | |
|             : name,
 | |
|         info.mName);
 | |
|     info.mSize = size.mSize;
 | |
|     info.mUnwriteableMargin = Some(MarginDouble{});
 | |
|   }
 | |
|   mCommonPaperInfo = std::move(localizedPaperInfo);
 | |
| }
 | 
