• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import { print } from '@kit.BasicServicesKit';
16import { BusinessError } from '@ohos.base';
17import CheckEmptyUtils from '../utils/CheckEmptyUtils';
18import { Log } from '../utils/Log';
19import { PrintUtil } from '../utils/PrintUtil';
20import { CustomPrintJobState } from '../model/PrintBean';
21import { StringUtil } from '../utils/StringUtil';
22
23const TAG: string = 'print_fwk';
24
25/**
26 * defines print attributes.
27 */
28export class PrintAttributes implements print.PrintAttributes {
29  copyNumber?: number;
30  pageRange?: PrinterRange;
31  pageSize?: PrintPageSize;
32  colorMode?: print.PrintColorMode;
33  duplexMode?: print.PrintDuplexMode;
34  directionMode?: print.PrintDirectionMode;
35  isSequential: boolean; /* Add a Variable */
36  isLandscape: boolean; /* Add a Variable */
37  options: string; /* Add a Variable */
38  margin: PrintMargin;
39
40  constructor(copyNumber: number, pageRange: PrinterRange,
41              isSequential: boolean, pageSize: PrintPageSize, isLandscape: boolean,
42              colorMode: print.PrintColorMode, duplexMode: print.PrintDuplexMode, margin: PrintMargin,
43              directionMode: print.PrintDirectionMode, options: string) {
44    this.copyNumber = copyNumber;
45    this.pageRange = pageRange;
46    this.pageSize = pageSize;
47    this.colorMode = colorMode;
48    this.duplexMode = duplexMode;
49    this.directionMode = directionMode;
50    this.isSequential = isSequential;
51    this.isLandscape = isLandscape;
52    this.margin = margin;
53    this.options = options;
54  }
55}
56
57/**
58 * defines print margin.
59 */
60export class PrintMargin implements print.PrintMargin {
61  top?: number;
62  bottom?: number;
63  left?: number;
64  right?: number;
65
66  constructor(top: number, bottom: number, left: number, right: number) {
67    this.top = top;
68    this.bottom = bottom;
69    this.left = left;
70    this.right = right;
71  }
72}
73
74/**
75 * defines print range.
76 */
77export class PrinterRange implements print.PrinterRange {
78  startPage?: number;
79  endPage?: number;
80  pages?: Array<number>;
81
82  constructor(startPage: number, endPage: number, pages: Array<number>) {
83    this.startPage = startPage;
84    this.endPage = endPage;
85    this.pages = pages;
86  }
87}
88
89/**
90 * defines print preview attribute.
91 */
92export class PreviewAttribute implements print.PreviewAttribute {
93  previewRange: PrinterRange;
94  result?: number;
95
96  constructor(previewRange: PrinterRange, result: number) {
97    this.previewRange = previewRange;
98    this.result = result;
99  }
100}
101
102/**
103 * defines print resolution.
104 */
105export class PrintResolution implements print.PrintResolution {
106  id: string;
107  horizontalDpi: number;
108  verticalDpi: number;
109}
110
111export class PrintPageSize implements print.PrintPageSize {
112  id: string;
113  name: string;
114  width: number;
115  height: number;
116
117  constructor(id: string, name: string, width: number, height: number) {
118    this.id = id;
119    this.name = name;
120    this.width = width;
121    this.height = height;
122  }
123}
124
125/**
126 * defines print capability.
127 */
128export class PrinterCapability implements print.PrinterCapability {
129  colorMode: number;
130  duplexMode: number;
131  pageSize: Array<PrintPageSize>;
132  resolution?: Array<PrintResolution>;
133  minMargin?: PrintMargin;
134  options?: string; /* Change Type*/
135}
136
137/**
138 * defines print info.
139 */
140export class PrinterInfo implements print.PrinterInfo {
141  printerId: string;
142  printerName: string;
143  printerState: print.PrinterState;
144  printerIcon?: number;
145  description?: string;
146  capability?: PrinterCapability;
147  options?: string;
148
149  constructor(printerId: string, printerName: string, printerState: print.PrinterState, printerIcon?: number, description?: string,
150              capability?: PrinterCapability, options?: string) {
151    this.printerId = printerId;
152    this.printerName = printerName;
153    this.printerState = printerState;
154    if (printerIcon) {
155      this.printerIcon = printerIcon;
156    }
157    if (description) {
158      this.description = description;
159    }
160    if (capability) {
161      this.capability = capability;
162    }
163    if (options) {
164      this.options = options;
165    }
166  }
167
168  toString(): string {
169    return '[PrinterInfo printerId:' + StringUtil.splitMac(this.printerId) +
170    ' ,printerName:' + StringUtil.encodeCommonString(this.printerName) +
171    ' , printerState:' + this.printerState + ']';
172  }
173}
174
175/**
176 * PrinterInfo.options数据结构
177 */
178export class PrinterCapsOptions {
179  supportedMediaTypes: number[];
180  supportedQualities: number[];
181  make: string;
182  printerUri: string;
183}
184
185/**
186 * defines print job
187 */
188export class PrintJob implements print.PrintJob {
189  jobFiles: Array<string>; /* Add a Variable */
190  fdList: Array<number>;
191  jobId: string;
192  printerId: string;
193  jobState: print.PrintJobState;
194  jobSubstate: print.PrintJobSubState;
195  copyNumber: number;
196  pageRange: PrinterRange;
197  isSequential: boolean;
198  pageSize: PrintPageSize;
199  isLandscape: boolean;
200  colorMode: number;
201  duplexMode: number;
202  margin: PrintMargin;
203  preview: PreviewAttribute;
204  options: string; /* Change Type */
205
206  constructor(jobFiles: Array<string>, fdList: Array<number>, jobId: string, printerId: string, jobState: print.PrintJobState,
207              jobSubstate: print.PrintJobSubState, copyNumber: number, pageRange: PrinterRange, isSequential: boolean,
208              pageSize: PrintPageSize, isLandscape: boolean, colorMode: number, duplexMode: number, margin: PrintMargin,
209              preview: PreviewAttribute, options: string) {
210    this.jobFiles = jobFiles;
211    this.fdList = fdList;
212    this.jobId = jobId;
213    this.printerId = printerId;
214    this.jobState = jobState;
215    this.jobSubstate = jobSubstate;
216    this.copyNumber = copyNumber;
217    this.pageRange = pageRange;
218    this.isSequential = isSequential;
219    this.pageSize = pageSize;
220    this.isLandscape = isLandscape;
221    this.colorMode = colorMode;
222    this.duplexMode = duplexMode;
223    this.margin = margin;
224    this.preview = preview;
225    this.options = options;
226  }
227}
228
229export class PrinterExtensionInfo implements print.PrinterExtensionInfo {
230  extensionId: string; // extension id of printer extension
231  vendorId: string; // vendor id of extension
232  vendorName: string;  // vendor name
233  vendorIcon: number; // resource id of vendor
234  version: string; // version of current printer extension
235  constructor(extensionId: string, vendorId: string, vendorName: string, vendorIcon: number, version: string) {
236    this.extensionId = extensionId;
237    this.vendorId = vendorId;
238    this.vendorName = vendorName;
239    this.vendorIcon = vendorIcon;
240    this.version = version;
241  }
242}
243
244/**
245 * PrintJob.options数据结构
246 */
247export class PrintJobOptions {
248  jobName: string;
249  jobNum: number;
250  jobDescription: string;
251  mediaType: string;
252  documentCategory: number;
253  printQuality: string;
254  printerName: string;
255  printerUri: string;
256  documentFormat: string;
257  files: string[];
258}
259export function startPrintJob(printJobInfo: PrintJob): Promise<boolean> {
260  Log.info(TAG, 'startPrintJob enter.');
261  return new Promise((resolve) => {
262    if (CheckEmptyUtils.isEmpty(printJobInfo)) {
263      Log.info(TAG, 'startPrintJob, printJobInfo invalid.');
264      return resolve(false);
265    }
266    let printJob: print.PrintJob = convertToFwkPrintJob(printJobInfo);
267    Log.info(TAG, 'startPrintJob, jobId =' + JSON.stringify(printJobInfo.jobId));
268    print.startPrintJob(printJob).then(() => {
269      Log.info(TAG, 'start print success.');
270      resolve(true);
271    }).catch((err: BusinessError) => {
272      Log.error(TAG, 'failed to start Print because ' + JSON.stringify(err));
273      return resolve(false);
274    });
275  });
276}
277
278export function queryAllPrintJobs(printerId?: string): Promise<Array<PrintJob>> {
279  return new Promise((resolve, reject) => {
280    print.queryPrintJobList().then((data: Array<print.PrintJob>) => {
281      Log.info(TAG, `queryAllPrintJobs data.length:${data.length}`);
282      let retPrintJobs: Array<PrintJob> = [];
283      for (let printJob of data) {
284        Log.debug(TAG, `queryAllPrintJobs printJob:${JSON.stringify(printJob)}`);
285        let printJobInfo = convertToSpoolerPrintJob(printJob);
286        if (CheckEmptyUtils.isEmpty(printJobInfo)) {
287          Log.warn(TAG, 'queryAllPrintJobs invalid job.');
288          continue;
289        }
290        if (CheckEmptyUtils.checkStrIsEmpty(printerId) || printJobInfo.printerId === printerId) {
291          retPrintJobs.push(printJobInfo);
292        }
293      }
294      Log.info(TAG, `queryAllPrintJobs retPrintJobs.length: ${retPrintJobs.length}`);
295      resolve(retPrintJobs);
296    }).catch((err: BusinessError) => {
297      Log.error(TAG, `failed to queryAllPrintJobs Cause: ${JSON.stringify(err)}`);
298      return reject(err);
299    });
300  });
301}
302
303export function cancelPrintJob(jobId: string): void {
304  Log.info(TAG, 'cancelPrintJob enter.');
305  if (CheckEmptyUtils.checkStrIsEmpty(jobId)) {
306    Log.info(TAG, 'cancelPrintJob, jobId is empty.');
307    return;
308  }
309  Log.info(TAG, 'cancelPrintJob jobId=' + jobId);
310  print.cancelPrintJob(jobId).then((data) => {
311    Log.info(TAG, 'cancel print success data: ' + JSON.stringify(data));
312  }).catch((error: BusinessError) => {
313    Log.error(TAG, 'cancel print failed, because: ' + JSON.stringify(error));
314  });
315  Log.info(TAG, 'cancelPrintJob end.');
316}
317
318export function isValidPrintJob(job: print.PrintJob): boolean {
319  if (CheckEmptyUtils.isEmpty(job)) {
320    Log.info(TAG, 'isValidPrintJob job is empty.');
321    return false;
322  }
323  if (CheckEmptyUtils.checkStrIsEmpty(job.printerId) || CheckEmptyUtils.checkStrIsEmpty(job.jobId) ||
324  !(PrintUtil.isValueInEnum(job.jobState, print.PrintJobState) || PrintUtil.isValueInEnum(job.jobState, CustomPrintJobState)) ||
325  !PrintUtil.isValueInEnum(job.jobSubstate, print.PrintJobSubState)) {
326    return false;
327  }
328  return true;
329}
330
331export function convertToSpoolerPrintJob(job: print.PrintJob): PrintJob {
332  if (!isValidPrintJob(job)) {
333    return null;
334  }
335  return new PrintJob([], job.fdList, job.jobId, job.printerId, job.jobState as print.PrintJobState, job.jobSubstate,
336    job.copyNumber, job.pageRange, job.isSequential, job.pageSize, job.isLandscape, job.colorMode,
337    job.duplexMode, job.margin, job.preview, job.options as string);
338}
339
340export function convertToFwkPrintJob(printJobInfo: PrintJob): print.PrintJob {
341  let pageRangeInfo: PrinterRange;
342  if (printJobInfo.pageRange.pages.length === 0) {
343    pageRangeInfo = { startPage: printJobInfo.pageRange.startPage, endPage: printJobInfo.pageRange.endPage };
344  } else {
345    pageRangeInfo = { pages: printJobInfo.pageRange.pages };
346  }
347  // remove: preview, jobFiles
348  let printJob: print.PrintJob = {
349    fdList: printJobInfo.fdList,
350    jobId: printJobInfo.jobId,
351    printerId: printJobInfo.printerId,
352    jobState: printJobInfo.jobState,
353    jobSubstate: printJobInfo.jobSubstate,
354    copyNumber: printJobInfo.copyNumber,
355    pageRange: pageRangeInfo,
356    isSequential: printJobInfo.isSequential,
357    pageSize: printJobInfo.pageSize,
358    isLandscape: printJobInfo.isLandscape,
359    colorMode: printJobInfo.colorMode,
360    duplexMode: printJobInfo.duplexMode,
361    margin: printJobInfo.margin,
362    options: printJobInfo.options
363  };
364  return printJob;
365}
366
367export function convertToPrinterInfo(info: print.PrinterInfo): PrinterInfo {
368  if (CheckEmptyUtils.isEmpty(info)) {
369    return null;
370  }
371  let printerInfo: PrinterInfo = new PrinterInfo(info.printerId, info.printerName, info.printerState, info.printerIcon, info.description,
372    info.capability as PrinterCapability, info.options as string);
373  return printerInfo;
374}
375