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 '@ohos.print';
16import { cancelPrintJob, CustomPrintJobState, Log, PrintItemChangeListener, PrintJob, SingletonHelper } from '@ohos/common';
17import { printJobMgr } from '../../Controller/PrintJobManager';
18import { PageData, PrintJobItem, ShowTips } from './PrintPageModel';
19
20const TAG: string = 'PrintJobViewModel';
21const COMPLETED_STATUS = 'completed';
22/**
23 * 打印任务状态-任务状态描述字串id映射集合
24 */
25const JOB_STATUS_MAP: Map<number, string> = new Map([
26  [print.PrintJobState.PRINT_JOB_PREPARE, 'print_job_created'],
27  [print.PrintJobState.PRINT_JOB_QUEUED, 'print_job_created'],
28  [print.PrintJobState.PRINT_JOB_RUNNING, 'print_job_printing'],
29  [print.PrintJobState.PRINT_JOB_BLOCKED, 'print_job_blocked'],
30  [CustomPrintJobState.PRINT_JOB_CANCELLING as number, 'print_job_cancelling'],
31  [print.PrintJobState.PRINT_JOB_COMPLETED, COMPLETED_STATUS]
32]);
33/**
34 * 打印任务完成状态-任务状态描述字串id映射集合
35 */
36const JOB_COMPLETED_MAP: Map<number, string> = new Map([
37  [print.PrintJobSubState.PRINT_JOB_COMPLETED_SUCCESS, 'print_job_completed'],
38  [print.PrintJobSubState.PRINT_JOB_COMPLETED_FAILED, 'print_job_failed'],
39  [print.PrintJobSubState.PRINT_JOB_COMPLETED_CANCELLED, 'print_job_cancelled']
40]);
41/**
42 * 横幅提示集合:
43 */
44const SHOW_TIPS_MAP: Map<number, string> = new Map([
45  [print.PrintJobSubState.PRINT_JOB_BLOCK_DOOR_OPEN, 'printer_door_open'],
46  [print.PrintJobSubState.PRINT_JOB_BLOCK_BUSY, 'printer_busy'],
47  [print.PrintJobSubState.PRINT_JOB_BLOCK_JAMMED, 'printer_jammed'],
48  [print.PrintJobSubState.PRINT_JOB_BLOCK_LOW_ON_INK, 'printer_low_on_ink'],
49  [print.PrintJobSubState.PRINT_JOB_BLOCK_OFFLINE, 'printer_offline'],
50  [print.PrintJobSubState.PRINT_JOB_BLOCK_LOW_ON_TONER, 'printer_low_on_toner'],
51  [print.PrintJobSubState.PRINT_JOB_BLOCK_OUT_OF_INK, 'printer_out_of_ink'],
52  [print.PrintJobSubState.PRINT_JOB_BLOCK_OUT_OF_PAPER, 'printer_out_of_paper'],
53  [print.PrintJobSubState.PRINT_JOB_BLOCK_OUT_OF_TONER, 'printer_out_of_tone'],
54  [print.PrintJobSubState.PRINT_JOB_BLOCK_REALLY_LOW_ON_INK, 'printer_out_of_ink'],
55  [print.PrintJobSubState.PRINT_JOB_BLOCK_SERVICE_REQUEST, 'printer_check'],
56  [print.PrintJobSubState.PRINT_JOB_BLOCK_BAD_CERTIFICATE, 'printer_bad_certificate'],
57  [print.PrintJobSubState.PRINT_JOB_BLOCK_NETWORK_ERROR, 'print_block_reason_network_error']
58]);
59/**
60 * 打印任务管理界面基础数据模型
61 */
62export class PrintJobViewModel {
63  private uiJobsMap: Map<string, PrintJobItem> = new Map();
64  private listener: PrintItemChangeListener | null = null;
65  private tips: ShowTips = new ShowTips();
66  aboutToAppear(listener: PrintItemChangeListener): void {
67    Log.info(TAG, 'aboutToAppear');
68    this.listener = listener;
69    printJobMgr.registerJobChangeListener(TAG, this);
70  }
71
72  aboutToDisappear(): void {
73    this.listener = null;
74    printJobMgr.unregisterJobChangeListener(TAG);
75    this.uiJobsMap.clear();
76  }
77
78  getPrintJobQueue(): void {
79    printJobMgr.getPrintJobQueue();
80  }
81
82  private getJobStateStrName(jobState: number, jobSubState: print.PrintJobSubState): string {
83    Log.debug(TAG, `getJobStateStrName enter jobState:${jobState}, jobSubState:${jobSubState}`);
84    let jobStateStrName = JOB_STATUS_MAP.get(jobState)!;
85    if (jobStateStrName === COMPLETED_STATUS) {
86      jobStateStrName = JOB_COMPLETED_MAP.get(jobSubState)!;
87    }
88    Log.debug(TAG, `getJobStateStrName end jobStateStrName:${jobStateStrName}`);
89    return jobStateStrName;
90  }
91
92  private updateShowTips(blockedSubState: number): void {
93    if (blockedSubState != -1) {
94      this.tips.isShowTips = true;
95      this.tips.showTipsText = SHOW_TIPS_MAP.get(blockedSubState)!;
96      this.tips.fontColor = $r('sys.color.ohos_id_color_warning');
97      this.tips.icon = $r('app.media.ic_print_warning_tips');
98    } else {
99      this.tips.isShowTips = false;
100      this.tips.showTipsText = '';
101    }
102  }
103
104  private getJobStateFontColor(jobState: number, jobSubState?: print.PrintJobSubState): Resource {
105    Log.debug(TAG, 'getJobStateFontColor enter jobState: ' + jobState + ' ,jobSubState:' + jobSubState);
106    let color: Resource;
107    if (jobState == print.PrintJobState.PRINT_JOB_BLOCKED) {
108      color = $r('app.color.text_jobState_blocked');
109    } else if (jobState == print.PrintJobState.PRINT_JOB_COMPLETED) {
110      color = $r('app.color.text_jobState_completed');
111    } else {
112      color = $r('app.color.text_jobState_running');
113    }
114    return color;
115  }
116
117  private isHideCancelBtn(jobState: number) : boolean {
118    return jobState == print.PrintJobState.PRINT_JOB_COMPLETED;
119  }
120
121  onAddPrintJob(job: PrintJob, blockedSubState: number) : void {
122    Log.info(TAG, 'onAddPrintJob enter.');
123    if (!this.uiJobsMap.has(job.jobId)) {
124      Log.info(TAG, `onAddPrintJob jobId:${job.jobId}, blockedSubState:${blockedSubState}`);
125      let jobStateStrName: string = this.getJobStateStrName(job.jobState as number, job.jobSubstate);
126      let jobStateFontColor: Resource = this.getJobStateFontColor(job.jobState as number, job.jobSubstate);
127      let jobItem: PrintJobItem = new PrintJobItem(job, this.isHideCancelBtn(job.jobState as number), jobStateFontColor, jobStateStrName);
128      Log.debug(TAG, `onAddPrintJob ${jobItem.toString()}`);
129      this.uiJobsMap.set(job.jobId, jobItem);
130      // 刷新横幅提示状态
131      this.updateShowTips(blockedSubState);
132      this.refreshUi();
133    }
134    Log.info(TAG, 'onAddPrintJob end.');
135  }
136
137  onUpdatePrintJob(job: PrintJob, blockedSubState: number): void {
138    Log.info(TAG, 'onUpdatePrintJob enter.');
139    let jobItem = this.uiJobsMap.get(job.jobId);
140    if (jobItem) {
141      Log.info(TAG, `onUpdatePrintJob jobId:${job.jobId}, blockedSubState:${blockedSubState}`);
142      jobItem.jobStateStrName = this.getJobStateStrName(job.jobState, job.jobSubstate);
143      jobItem.isHideCancelBtn = this.isHideCancelBtn(job.jobState as number);
144      jobItem.jobStateColor = this.getJobStateFontColor(job.jobState as number, job.jobSubstate);
145      Log.debug(TAG, `onUpdatePrintJob ${jobItem.toString()}`);
146      this.uiJobsMap.set(job.jobId, jobItem);
147      // 刷新横幅提示状态
148      this.updateShowTips(blockedSubState);
149      this.refreshUi();
150    }
151    Log.info(TAG, 'onUpdatePrintJob end.');
152  }
153
154  onRemovePrintJob(jobId: string, blockedSubState: number): void {
155    Log.info(TAG, 'onRemovePrintJob enter.');
156    if (this.uiJobsMap.delete(jobId)) {
157      Log.info(TAG, `onRemovePrintJob success, jobId:${jobId}, blockedSubState:${blockedSubState}`);
158      // 刷新横幅提示状态
159      this.updateShowTips(blockedSubState);
160      this.refreshUi();
161    }
162    Log.info(TAG, 'onRemovePrintJob end.');
163  }
164
165  onAllPrintJobsFinished(): void {
166    Log.info(TAG, 'onAllPrintJobsFinished enter.');
167    this.uiJobsMap.clear();
168    // 刷新横幅提示状态
169    this.updateShowTips(-1);
170    this.refreshUi();
171    Log.info(TAG, 'onAllPrintJobsFinished end.');
172  }
173
174  cancelPrintJob(jobId: string): void {
175    Log.debug(TAG, 'cancelPrintJob enter.');
176    let jobItem = this.uiJobsMap.get(jobId);
177    if (jobItem) {
178      Log.info(TAG, `cancelPrintJob jobId:${jobId}`);
179      jobItem.jobStateStrName = JOB_STATUS_MAP.get(CustomPrintJobState.PRINT_JOB_CANCELLING as number)!;
180      jobItem.jobStateColor = this.getJobStateFontColor(CustomPrintJobState.PRINT_JOB_CANCELLING as number)!;
181      Log.debug(TAG, `cancelPrintJob ${jobItem.toString()}`);
182      this.uiJobsMap.set(jobId, jobItem);
183      this.refreshUi();
184    }
185    cancelPrintJob(jobId);
186    Log.info(TAG, 'cancelPrintJob end.');
187  }
188
189  refreshUi(): void {
190    Log.info(TAG, 'refreshUi enter.');
191    if (this.listener == null) {
192      return;
193    }
194    let jobList: Array<PrintJobItem> = new Array();
195    this.uiJobsMap.forEach((value, key) => {
196      jobList.push(value);
197    })
198    let pageData: PageData = new PageData(this.tips, jobList);
199    Log.info(TAG, `refreshUi pageData: ${pageData.toString()}`);
200    this.listener.onPrintItemsChanged(pageData);
201    Log.info(TAG, 'refreshUi end.');
202  }
203}
204export let printJobMgrVM = SingletonHelper.getInstance(PrintJobViewModel, TAG);
205