1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsPrinterListBase.h"
7 #include "PrintBackgroundTask.h"
8 #include "mozilla/ErrorResult.h"
9 #include "mozilla/gfx/Rect.h"
10 #include "mozilla/IntegerRange.h"
11 #include "mozilla/intl/Localization.h"
12 #include "mozilla/Maybe.h"
13 #include "mozilla/RefPtr.h"
14 #include "xpcpublic.h"
16 using namespace mozilla
;
18 using mozilla::ErrorResult
;
19 using mozilla::intl::Localization
;
20 using PrinterInfo
= nsPrinterListBase::PrinterInfo
;
21 using MarginDouble
= mozilla::gfx::MarginDouble
;
23 nsPrinterListBase::nsPrinterListBase() = default;
24 nsPrinterListBase::~nsPrinterListBase() = default;
26 NS_IMPL_CYCLE_COLLECTION(nsPrinterListBase
, mPrintersPromise
)
28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterListBase
)
29 NS_INTERFACE_MAP_ENTRY(nsIPrinterList
)
30 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIPrinterList
)
33 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterListBase
)
34 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterListBase
)
39 void ResolveOrReject(dom::Promise
& aPromise
, nsPrinterListBase
& aList
,
40 const nsTArray
<PrinterInfo
>& aInfo
) {
41 nsTArray
<RefPtr
<nsIPrinter
>> printers
;
42 printers
.SetCapacity(aInfo
.Length());
43 for (auto& info
: aInfo
) {
44 printers
.AppendElement(aList
.CreatePrinter(info
));
46 aPromise
.MaybeResolve(printers
);
50 void ResolveOrReject(dom::Promise
& aPromise
, nsPrinterListBase
& aList
,
51 const Maybe
<PrinterInfo
>& aInfo
) {
53 aPromise
.MaybeResolve(aList
.CreatePrinter(aInfo
.value()));
55 aPromise
.MaybeRejectWithNotFoundError("Printer not found");
59 } // namespace mozilla
61 NS_IMETHODIMP
nsPrinterListBase::GetPrinters(JSContext
* aCx
,
63 EnsureCommonPaperInfo(aCx
);
64 return mozilla::AsyncPromiseAttributeGetter(
65 *this, mPrintersPromise
, aCx
, aResult
, &nsPrinterListBase::Printers
);
68 NS_IMETHODIMP
nsPrinterListBase::GetPrinterByName(const nsAString
& aPrinterName
,
71 EnsureCommonPaperInfo(aCx
);
72 return PrintBackgroundTaskPromise(*this, aCx
, aResult
,
73 &nsPrinterListBase::PrinterByName
,
74 nsString
{aPrinterName
});
77 NS_IMETHODIMP
nsPrinterListBase::GetPrinterBySystemName(
78 const nsAString
& aPrinterName
, JSContext
* aCx
, Promise
** aResult
) {
79 EnsureCommonPaperInfo(aCx
);
80 return PrintBackgroundTaskPromise(*this, aCx
, aResult
,
81 &nsPrinterListBase::PrinterBySystemName
,
82 nsString
{aPrinterName
});
85 NS_IMETHODIMP
nsPrinterListBase::GetNamedOrDefaultPrinter(
86 const nsAString
& aPrinterName
, JSContext
* aCx
, Promise
** aResult
) {
87 EnsureCommonPaperInfo(aCx
);
88 return PrintBackgroundTaskPromise(*this, aCx
, aResult
,
89 &nsPrinterListBase::NamedOrDefaultPrinter
,
90 nsString
{aPrinterName
});
93 Maybe
<PrinterInfo
> nsPrinterListBase::NamedOrDefaultPrinter(
94 nsString aName
) const {
95 if (Maybe
<PrinterInfo
> value
= PrinterByName(std::move(aName
))) {
99 // Since the name had to be passed by-value, we can re-use it to fetch the
100 // default printer name, potentially avoiding an extra string allocation.
101 if (NS_SUCCEEDED(SystemDefaultPrinterName(aName
))) {
102 return PrinterByName(std::move(aName
));
108 NS_IMETHODIMP
nsPrinterListBase::GetFallbackPaperList(JSContext
* aCx
,
111 nsCOMPtr
<nsIGlobalObject
> global
= xpc::CurrentNativeGlobal(aCx
);
112 RefPtr
<Promise
> promise
= Promise::Create(global
, rv
);
113 if (MOZ_UNLIKELY(rv
.Failed())) {
115 return rv
.StealNSResult();
118 EnsureCommonPaperInfo(aCx
);
119 nsTArray
<RefPtr
<nsPaper
>> papers
;
120 papers
.SetCapacity(nsPaper::kNumCommonPaperSizes
);
121 for (const auto& info
: *mCommonPaperInfo
) {
122 papers
.AppendElement(MakeRefPtr
<nsPaper
>(info
));
125 promise
->MaybeResolve(papers
);
126 promise
.forget(aResult
);
130 void nsPrinterListBase::EnsureCommonPaperInfo(JSContext
* aCx
) {
131 MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
132 if (mCommonPaperInfo
) {
135 RefPtr
<CommonPaperInfoArray
> localizedPaperInfo
=
136 MakeRefPtr
<CommonPaperInfoArray
>();
137 CommonPaperInfoArray
& paperArray
= *localizedPaperInfo
;
138 // Apply localization to the names while constructing the PaperInfo, if
139 // available (otherwise leave them as the internal keys, which are at least
140 // somewhat recognizable).
141 IgnoredErrorResult rv
;
142 nsTArray
<nsCString
> resIds
= {
143 "toolkit/printing/printUI.ftl"_ns
,
145 RefPtr
<Localization
> l10n
= Localization::Create(resIds
, true);
147 for (auto i
: IntegerRange(nsPaper::kNumCommonPaperSizes
)) {
148 const CommonPaperSize
& size
= nsPaper::kCommonPaperSizes
[i
];
149 PaperInfo
& info
= paperArray
[i
];
151 nsAutoCString key
{"printui-paper-"};
152 key
.Append(size
.mLocalizableNameKey
);
154 l10n
->FormatValueSync(key
, {}, name
, rv
);
156 // Fill out the info with our PWG size and the localized name.
157 info
.mId
= size
.mPWGName
;
159 (rv
.Failed() || name
.IsEmpty())
160 ? static_cast<const nsCString
&>(size
.mLocalizableNameKey
)
163 info
.mSize
= size
.mSize
;
164 info
.mUnwriteableMargin
= Some(MarginDouble
{});
166 mCommonPaperInfo
= std::move(localizedPaperInfo
);