2020-08-07 15:04:26 +03:00
|
|
|
/* -*- 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"
|
2020-08-10 01:05:57 +03:00
|
|
|
#include "PrintBackgroundTask.h"
|
|
|
|
#include "mozilla/ErrorResult.h"
|
2021-11-15 15:39:38 +03:00
|
|
|
#include "mozilla/gfx/Rect.h"
|
|
|
|
#include "mozilla/IntegerRange.h"
|
2020-09-17 23:05:16 +03:00
|
|
|
#include "mozilla/intl/Localization.h"
|
2021-11-15 15:39:38 +03:00
|
|
|
#include "mozilla/Maybe.h"
|
|
|
|
#include "mozilla/RefPtr.h"
|
2020-08-10 01:05:57 +03:00
|
|
|
#include "xpcpublic.h"
|
|
|
|
|
2021-11-15 15:39:38 +03:00
|
|
|
using namespace mozilla;
|
|
|
|
|
2020-08-10 01:05:57 +03:00
|
|
|
using mozilla::ErrorResult;
|
2020-09-17 23:05:16 +03:00
|
|
|
using mozilla::intl::Localization;
|
2020-08-10 01:05:57 +03:00
|
|
|
using PrinterInfo = nsPrinterListBase::PrinterInfo;
|
2021-11-15 15:39:38 +03:00
|
|
|
using MarginDouble = mozilla::gfx::MarginDouble;
|
2020-08-07 15:04:26 +03:00
|
|
|
|
|
|
|
nsPrinterListBase::nsPrinterListBase() = default;
|
|
|
|
nsPrinterListBase::~nsPrinterListBase() = default;
|
|
|
|
|
2020-08-10 01:05:57 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2020-08-20 14:59:46 +03:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-10 01:05:57 +03:00
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPrinterListBase::GetPrinters(JSContext* aCx,
|
|
|
|
Promise** aResult) {
|
2020-10-14 00:52:04 +03:00
|
|
|
EnsureCommonPaperInfo(aCx);
|
2020-08-31 17:36:45 +03:00
|
|
|
return mozilla::AsyncPromiseAttributeGetter(*this, mPrintersPromise, aCx,
|
|
|
|
aResult, "Printers"_ns,
|
|
|
|
&nsPrinterListBase::Printers);
|
2020-08-10 01:05:57 +03:00
|
|
|
}
|
2020-08-20 14:59:46 +03:00
|
|
|
|
2020-09-16 00:23:27 +03:00
|
|
|
NS_IMETHODIMP nsPrinterListBase::GetPrinterByName(const nsAString& aPrinterName,
|
|
|
|
JSContext* aCx,
|
|
|
|
Promise** aResult) {
|
2020-10-14 00:52:04 +03:00
|
|
|
EnsureCommonPaperInfo(aCx);
|
2020-09-16 00:23:27 +03:00
|
|
|
return PrintBackgroundTaskPromise(*this, aCx, aResult, "PrinterByName"_ns,
|
|
|
|
&nsPrinterListBase::PrinterByName,
|
2020-08-20 14:59:46 +03:00
|
|
|
nsString{aPrinterName});
|
|
|
|
}
|
|
|
|
|
2020-09-16 00:23:27 +03:00
|
|
|
NS_IMETHODIMP nsPrinterListBase::GetPrinterBySystemName(
|
|
|
|
const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
|
2020-10-14 00:52:04 +03:00
|
|
|
EnsureCommonPaperInfo(aCx);
|
2020-09-16 00:23:27 +03:00
|
|
|
return PrintBackgroundTaskPromise(
|
|
|
|
*this, aCx, aResult, "PrinterBySystemName"_ns,
|
|
|
|
&nsPrinterListBase::PrinterBySystemName, nsString{aPrinterName});
|
|
|
|
}
|
|
|
|
|
2020-08-20 14:59:46 +03:00
|
|
|
NS_IMETHODIMP nsPrinterListBase::GetNamedOrDefaultPrinter(
|
|
|
|
const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
|
2020-10-14 00:52:04 +03:00
|
|
|
EnsureCommonPaperInfo(aCx);
|
2020-08-31 17:36:45 +03:00
|
|
|
return PrintBackgroundTaskPromise(
|
|
|
|
*this, aCx, aResult, "NamedOrDefaultPrinter"_ns,
|
|
|
|
&nsPrinterListBase::NamedOrDefaultPrinter, nsString{aPrinterName});
|
2020-08-20 14:59:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
Maybe<PrinterInfo> nsPrinterListBase::NamedOrDefaultPrinter(
|
|
|
|
nsString aName) const {
|
2020-09-16 00:23:27 +03:00
|
|
|
if (Maybe<PrinterInfo> value = PrinterByName(std::move(aName))) {
|
2020-08-20 14:59:46 +03:00
|
|
|
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))) {
|
2020-09-16 00:23:27 +03:00
|
|
|
return PrinterByName(std::move(aName));
|
2020-08-20 14:59:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return Nothing();
|
|
|
|
}
|
2020-08-26 14:10:32 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP nsPrinterListBase::GetFallbackPaperList(JSContext* aCx,
|
|
|
|
Promise** aResult) {
|
2020-09-17 23:05:16 +03:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2020-10-14 00:53:47 +03:00
|
|
|
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
|
2020-09-17 23:05:16 +03:00
|
|
|
// available (otherwise leave them as the internal keys, which are at least
|
|
|
|
// somewhat recognizable).
|
2020-10-14 00:53:47 +03:00
|
|
|
IgnoredErrorResult rv;
|
2021-08-03 19:25:10 +03:00
|
|
|
nsTArray<nsCString> resIds = {
|
|
|
|
"toolkit/printing/printUI.ftl"_ns,
|
|
|
|
};
|
|
|
|
RefPtr<Localization> l10n = Localization::Create(resIds, true);
|
2020-08-26 14:10:32 +03:00
|
|
|
|
2020-10-14 00:53:47 +03:00
|
|
|
for (auto i : IntegerRange(nsPaper::kNumCommonPaperSizes)) {
|
|
|
|
const CommonPaperSize& size = nsPaper::kCommonPaperSizes[i];
|
|
|
|
PaperInfo& info = paperArray[i];
|
|
|
|
|
|
|
|
nsAutoCString key{"printui-paper-"};
|
|
|
|
key.Append(size.mLocalizableNameKey);
|
2020-09-17 23:05:16 +03:00
|
|
|
nsAutoCString name;
|
2021-08-03 19:25:10 +03:00
|
|
|
l10n->FormatValueSync(key, {}, name, rv);
|
2020-08-26 14:10:32 +03:00
|
|
|
|
2020-10-14 00:53:47 +03:00
|
|
|
// 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);
|
2020-08-26 14:10:32 +03:00
|
|
|
}
|