summaryrefslogtreecommitdiffstats
path: root/widget/nsPrinterListBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/nsPrinterListBase.cpp')
-rw-r--r--widget/nsPrinterListBase.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/widget/nsPrinterListBase.cpp b/widget/nsPrinterListBase.cpp
new file mode 100644
index 0000000000..a362474cb5
--- /dev/null
+++ b/widget/nsPrinterListBase.cpp
@@ -0,0 +1,168 @@
+/* -*- 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);
+}