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