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 CheckEmptyUtils, {Constants, Log, StringUtil } from '@ohos/common'; 16import { GlobalThisHelper, GlobalThisStorageKey} from '@ohos/common'; 17import Util from '../Common/Utils/Util'; 18import common from '@ohos.app.ability.common'; 19import { PageData, PrintJobItem, ShowTips } from '../Model/JobViewModel/PrintPageModel'; 20import { printJobMgrVM, PrintJobViewModel } from '../Model/JobViewModel/PrintJobViewModel'; 21 22const TAG = '[JobManagerPage]' 23@Entry 24@Component 25struct JobManagerPage { 26 @Provide('Context') abilityContext : common.UIAbilityContext | undefined = undefined; 27 @State uiJobQueue: Array<PrintJobItem> = new Array<PrintJobItem>(); 28 @State tips: ShowTips = new ShowTips(); 29 private viewModel: PrintJobViewModel = printJobMgrVM; 30 private delayCloseTimer: number = -1; 31 build() { 32 Column(){ 33 Column(){ 34 Text($r('app.string.print_job')).key('JobManagerPage_Text_printJob') 35 .fontSize($r('app.float.font_size_headline8')) 36 .fontWeight(FontWeight.Medium) 37 .maxLines(Constants.NUMBER_1) 38 .textOverflow({overflow:TextOverflow.Ellipsis}) 39 Text(this.getPrinterName()).key('JobManagerPage_Text_printerName') 40 .fontSize($r('app.float.font_size_body2')) 41 .fontWeight(FontWeight.Regular) 42 .maxLines(Constants.NUMBER_1) 43 .textOverflow({overflow:TextOverflow.Ellipsis}) 44 } 45 .justifyContent(FlexAlign.Center) 46 .alignItems(HorizontalAlign.Start) 47 .width($r('app.float.print_job_comp_width')) 48 .height($r('app.float.print_job_title_height')) 49 .margin({left:$r('app.float.print_job_margin_left'),right:$r('app.float.print_job_margin_right')}) 50 Row(){ 51 Image($r('app.media.ic_printer_tips')).key('JobManagerPage_Image_printerTips') 52 .width($r('app.float.image_comp_width')) 53 .height($r('app.float.image_comp_height')) 54 .margin({right:$r('app.float.print_job_tips_image_margin_right')}) 55 Text(StringUtil.getStringByName(this.tips.showTipsText, this.abilityContext)).key('JobManagerPage_Text_blockedReason') 56 .fontSize($r('app.float.font_size_body2')) 57 .fontColor(this.tips.fontColor) 58 .fontWeight(FontWeight.Regular) 59 } 60 .width($r('app.float.print_job_comp_width')) 61 .margin({left:$r('app.float.print_job_margin_left'),right:$r('app.float.print_job_margin_right')}) 62 .visibility(this.tips.isShowTips?Visibility.Visible:Visibility.None) 63 64 Row() { 65 List() { 66 ForEach(this.uiJobQueue, (jobItem: PrintJobItem)=>{ 67 ListItem(){ 68 printJobComponent({ item: jobItem, 69 compId: 'JobManagerPage_printJobComponent_'+ jobItem.jobId, 70 action: () => { 71 this.viewModel.cancelPrintJob(jobItem.jobId); 72 } 73 }); 74 }.key(`JobManagerPage_ListItem_${jobItem.jobId}`) 75 }, (jobItem: PrintJobItem)=>jobItem.getKey()) 76 } 77 .key('JobManagerPage_List_jobQueue') 78 .edgeEffect(EdgeEffect.Spring) 79 .divider({ strokeWidth: $r('app.float.print_job_item_divider_strokeWidth') 80 , color: $r('app.color.divider_color'), startMargin: $r('app.float.print_job_item_divider_startMargin')}) 81 } 82 .width($r('app.float.print_job_comp_width')) 83 .height($r('app.float.print_job_height')) 84 .margin({left:$r('app.float.print_job_margin_left'),right:$r('app.float.print_job_margin_right')}) 85 .alignItems(VerticalAlign.Top) 86 Button($r('app.string.JobManagerPage_ok')).key('JobManagerPage_Button_confirmed') 87 .fontColor($r('app.color.button_cancel_text')) 88 .backgroundColor($r('app.color.button_color_cancel')) 89 .width($r('app.float.print_job_button_width')) 90 .height($r('app.float.print_job_button_height')) 91 .margin({top:$r('app.float.print_job_button_margin_top'),bottom:$r('app.float.print_job_button_margin_bottom')}) 92 .onClick(()=>{ 93 this.abilityContext?.terminateSelf().then((data) => { 94 Log.info('===>terminateSelfCallBack===>: '+data); 95 }); 96 }) 97 } 98 .width('100%') 99 .height('100%') 100 .backgroundColor(Color.White) 101 .alignItems(HorizontalAlign.Center) 102 } 103 104 aboutToAppear() { 105 this.abilityContext = GlobalThisHelper.getValue<common.UIAbilityContext>(GlobalThisStorageKey.KEY_JOB_MANAGER_ABILITY_CONTEXT); 106 } 107 108 onPageShow() { 109 Log.debug(TAG, 'onPageShow'); 110 this.viewModel.aboutToAppear(this); 111 this.viewModel.getPrintJobQueue(); 112 } 113 114 onPageHide() { 115 Log.debug(TAG, 'onPageHide'); 116 this.viewModel.aboutToDisappear(); 117 } 118 119 onPrintItemsChanged(data: PageData) { 120 Log.info(TAG, 'onPrintItemsChanged enter.'); 121 this.tips = data.tips; 122 this.uiJobQueue = data.uiJobQueue; 123 Log.info(TAG, `onPrintItemsChanged length:${this.uiJobQueue.length}, tips:${this.tips.toString()}`); 124 if (this.uiJobQueue.length === 0) { 125 this.delayCloseTimer = setTimeout(() => { 126 this.abilityContext?.terminateSelf().then((data) => { 127 Log.info(TAG, 'all print jobs has been finished, '+data); 128 }); 129 }, Constants.SHOW_JOB_COMPLETED_TIMEOUT); 130 } else { 131 if (this.delayCloseTimer !== -1) { 132 clearTimeout(this.delayCloseTimer); 133 this.delayCloseTimer = -1; 134 } 135 } 136 } 137 138 getPrinterName(): string { 139 let printerName = ''; 140 let printerInfo = Util.getLastUsedPrinterInfo(this.abilityContext); 141 if (!CheckEmptyUtils.isEmpty(printerInfo)) { 142 printerName = printerInfo.printerName; 143 } 144 return printerName; 145 } 146} 147 148@Component 149struct printJobComponent { 150 item?: PrintJobItem; 151 compId?: string; 152 action?: () => void; 153 @Consume('Context') context : common.UIAbilityContext 154 @State imagePath: Resource = $r('app.media.ic_delete') 155 156 build(){ 157 Flex({justifyContent: FlexAlign.SpaceBetween, alignItems:ItemAlign.Center}) { 158 Image(this.item!.fileNum > Constants.NUMBER_1 ? $r('app.media.ic_two') : $r('app.media.ic_one')) 159 .width($r('app.float.image_comp_width')).height($r('app.float.image_comp_height')).objectFit(ImageFit.Contain).flexGrow(0).flexShrink(0).key(this.compId + '_image') 160 Column() { 161 Text(this.item?.jobTitleText) 162 .fontSize($r('sys.float.ohos_id_text_size_body3')) 163 .fontWeight(FontWeight.Regular) 164 .fontFamily('sans-serif') 165 .fontStyle(FontStyle.Normal) 166 .fontColor($r('sys.color.ohos_id_color_primary')) 167 .textOverflow({ overflow: TextOverflow.Ellipsis }) 168 .maxLines(1) 169 .key(this.compId + '_jobTitle') 170 Text(this.item!.jobDescriptionText) 171 .fontSize($r('sys.float.ohos_id_text_size_body3')) 172 .fontWeight(FontWeight.Regular) 173 .fontFamily('sans-serif') 174 .fontStyle(FontStyle.Normal) 175 .fontColor($r('sys.color.ohos_id_color_secondary')) 176 .textOverflow({ overflow: TextOverflow.Ellipsis }) 177 .maxLines(1) 178 .margin({ top: '2vp', bottom: '2vp' }) 179 .key(this.compId + '_jobDescriptionText') 180 Text(this.context?.resourceManager?.getStringByNameSync(this.item!.jobStateStrName) ?? '') 181 .fontSize($r('sys.float.ohos_id_text_size_body3')) 182 .fontColor(this.item!.jobStateColor) 183 .fontWeight(FontWeight.Regular) 184 .textOverflow({ overflow: TextOverflow.Ellipsis }) 185 .key(this.compId + '_jobStateStrName') 186 } 187 .alignItems(HorizontalAlign.Start).justifyContent(FlexAlign.SpaceBetween) 188 .width($r('app.float.print_job_item_des_width')) 189 .margin({right: '12vp'}) 190 191 Image(this.imagePath).width($r('app.float.image_comp_width')).height($r('app.float.image_comp_height')).objectFit(ImageFit.Contain) 192 .visibility(this.item!.isHideCancelBtn ? Visibility.Hidden:Visibility.Visible) 193 .key(this.compId + '_deleteBtn') 194 .onHover((isHover: boolean) => { 195 if (isHover) { 196 this.imagePath = $r('app.media.ic_delete_hover'); 197 } else { 198 this.imagePath = $r('app.media.ic_delete'); 199 } 200 }) 201 .onTouch((event: TouchEvent) => { 202 if (event.type === TouchType.Down) { 203 this.imagePath = $r('app.media.ic_delete_press'); 204 } 205 if (event.type === TouchType.Up) { 206 this.imagePath = $r('app.media.ic_delete'); 207 } 208 209 }) 210 .onClick(this.action) 211 } 212 .height($r('app.float.print_job_item_height')) 213 .padding({top :'4vp', bottom: '4vp'}) 214 } 215}