1/** 2 * Copyright (c) 2021-2022 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 */ 15 16import { Log } from '../utils/Log'; 17import { EventConstants } from '../constants/EventConstants'; 18import { CommonConstants } from '../constants/CommonConstants'; 19import { CardItemInfo } from '../bean/CardItemInfo'; 20import { SettingsModel } from './SettingsModel'; 21import { FormManager } from '../manager/FormManager'; 22import { RdbStoreManager } from '../manager/RdbStoreManager'; 23import { FormListInfoCacheManager } from '../cache/FormListInfoCacheManager'; 24import { PageDesktopModel } from './PageDesktopModel'; 25 26const TAG = 'FormModel'; 27const KEY_FORM_LIST = 'formListInfo'; 28 29/** 30 * form model. 31 */ 32export class FormModel { 33 private readonly mRdbStoreManager: RdbStoreManager; 34 private readonly mFormManager: FormManager; 35 private readonly mFormListInfoCacheManager: FormListInfoCacheManager; 36 private readonly mAppItemFormInfoMap = new Map<string, CardItemInfo[]>(); 37 private readonly mPageDesktopModel: PageDesktopModel; 38 39 private constructor() { 40 this.mRdbStoreManager = RdbStoreManager.getInstance(); 41 this.mFormManager = FormManager.getInstance(); 42 this.mFormListInfoCacheManager = FormListInfoCacheManager.getInstance(); 43 this.mPageDesktopModel = PageDesktopModel.getInstance(); 44 } 45 46 /** 47 * Get the form model object. 48 * 49 * @return {object} form model singleton 50 */ 51 static getInstance(): FormModel { 52 if (globalThis.FormModelInstance == null) { 53 globalThis.FormModelInstance = new FormModel(); 54 } 55 return globalThis.FormModelInstance; 56 } 57 58 /** 59 * Get the form info list of all ohos applications on the device. 60 * 61 * @return {array} allFormList 62 */ 63 async getAllFormsInfo() { 64 Log.showDebug(TAG, 'getAllFormsInfo start'); 65 const allFormList = await this.mFormManager.getAllFormsInfo(); 66 return allFormList; 67 } 68 69 /** 70 * Get the form info list of all ohos applications on the device by bundle name. 71 * 72 * @param {array} bundleName 73 * @param {function | undefined} callback 74 * 75 * @return {array} currentBundleFormsInfo 76 */ 77 async getFormsInfoByBundleName(bundleName: string, callback?) { 78 Log.showDebug(TAG, `getFormsInfoByBundleName bundleName: ${bundleName}`); 79 let currentBundleFormsInfo: any; 80 await this.mFormManager.getFormsInfoByApp(bundleName) 81 .then(bundleFormsInfo => { 82 currentBundleFormsInfo = bundleFormsInfo; 83 if (callback != undefined) { 84 callback(bundleName, bundleFormsInfo); 85 } 86 }) 87 .catch(err => { 88 Log.showError(TAG, `getFormsInfoByBundleName err: ${JSON.stringify(err)}`); 89 }); 90 AppStorage.SetOrCreate('formMgrItem', currentBundleFormsInfo); 91 return currentBundleFormsInfo; 92 } 93 94 /** 95 * Get the form info list of all ohos applications on the device by module name. 96 * 97 * @param {string} bundleName 98 * @param {string} moduleName 99 * 100 * @return {array} currentModuleFormsInfo 101 */ 102 async getFormsInfoByModuleName(bundleName: string, moduleName: string) { 103 Log.showDebug(TAG, `getFormsInfoByModuleName bundleName: ${bundleName}, moduleName: ${moduleName}`); 104 const currentModuleFormsInfo = await this.mFormManager.getFormsInfoByModule(bundleName, moduleName); 105 return currentModuleFormsInfo; 106 } 107 108 /** 109 * Get the form info list from rdb. 110 * 111 * @return {array} allFormList 112 */ 113 async getAllFormsInfoFromRdb() { 114 Log.showDebug(TAG, 'getAllFormsInfoFromRdb start'); 115 const allFormList = await this.mRdbStoreManager.getAllFormInfos(); 116 return allFormList; 117 } 118 119 /** 120 * Update the form info in rdb by id. 121 * 122 * @param {object} cardItemInfo 123 * 124 * @return {boolean} result 125 */ 126 async updateFormInfoById(cardItemInfo) { 127 return await this.mRdbStoreManager.updateFormInfoById(cardItemInfo); 128 } 129 130 /** 131 * Delete form in rdb and fms by id. 132 * 133 * @param {number} cardId 134 */ 135 async deleteFormById(cardId: number): Promise<boolean> { 136 try{ 137 await this.mRdbStoreManager.deleteFormInfoById(cardId); 138 await this.mFormManager.deleteCard(cardId.toString()); 139 } catch(error){ 140 Log.showError(TAG, `deleteFormById err: ${JSON.stringify(error)}`); 141 return false; 142 } 143 return true; 144 145 } 146 147 /** 148 * Delete form in fms by formId. 149 * 150 * @param {number} formId 151 */ 152 deleteFormByFormID(formId: number) { 153 this.mFormManager.deleteCard(formId.toString()); 154 } 155 156 /** 157 * Set app item form info into map. 158 * 159 * @param {string} bundleName 160 * @param {array} appItemFormInfo 161 */ 162 setAppItemFormInfo(bundleName: string, appItemFormInfo: CardItemInfo[]): void { 163 this.mAppItemFormInfoMap.set(bundleName, appItemFormInfo); 164 } 165 166 /** 167 * Get app item form info from map. 168 * 169 * @param {string} bundleName 170 * 171 * @return {array | undefined} mAppItemFormInfoMap 172 */ 173 getAppItemFormInfo(bundleName: string): CardItemInfo[] | undefined { 174 Log.showDebug(TAG, `getAppItemFormInfo bundleName: ${bundleName}, 175 appItemFormInfo: ${JSON.stringify(this.mAppItemFormInfoMap.get(bundleName))}`); 176 return this.mAppItemFormInfoMap.get(bundleName); 177 } 178 179 /** 180 * Update app item form info into map. 181 * 182 * @param {string} bundleName 183 * @param {string | undefined} eventType 184 */ 185 updateAppItemFormInfo(bundleName: string, eventType?: string): void { 186 if (eventType && eventType === EventConstants.EVENT_PACKAGE_REMOVED) { 187 this.mAppItemFormInfoMap.delete(bundleName); 188 return; 189 } 190 const formsInfoList = this.getFormsInfoByBundleName(bundleName, this.setAppItemFormInfo.bind(this)); 191 } 192 193 /** 194 * Delete form by bundleName and update layout info. 195 * 196 * @param {string} bundleName 197 */ 198 deleteFormByBundleName(bundleName: string): void { 199 const settingsModel = SettingsModel.getInstance(); 200 this.mRdbStoreManager.deleteFormInfoByBundle(bundleName); 201 const formInfoList: any = this.mFormListInfoCacheManager.getCache(KEY_FORM_LIST); 202 if (formInfoList === CommonConstants.INVALID_VALUE) { 203 return; 204 } 205 const layoutInfo = settingsModel.getLayoutInfo(); 206 const tempFormInfoList = JSON.parse(JSON.stringify(formInfoList)); 207 const pageItemMap = new Map<string, number>(); 208 for (let i = 0; i < layoutInfo.layoutInfo.length; i++) { 209 const tmpPage = layoutInfo.layoutInfo[i].page.toString(); 210 if (pageItemMap.has(tmpPage)) { 211 pageItemMap.set(tmpPage, pageItemMap.get(tmpPage) + 1); 212 } else { 213 pageItemMap.set(tmpPage, 1); 214 } 215 } 216 for(let i = formInfoList.length - 1; i >= 0; i--) { 217 const formInfo = formInfoList[i]; 218 if (formInfo.bundleName === bundleName) { 219 tempFormInfoList.splice(i, 1); 220 for(let j = layoutInfo.layoutInfo.length - 1; j >= 0; j--) { 221 if (layoutInfo.layoutInfo[j].typeId === CommonConstants.TYPE_CARD && formInfo.cardId == layoutInfo.layoutInfo[j].cardId) { 222 const tmpPage = layoutInfo.layoutInfo[j].page.toString(); 223 pageItemMap.set(tmpPage, pageItemMap.get(tmpPage) - 1); 224 layoutInfo.layoutInfo.splice(j, 1); 225 break; 226 } 227 } 228 } 229 } 230 if (tempFormInfoList.length === 0) { 231 this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, null); 232 } else { 233 this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, tempFormInfoList); 234 } 235 236 this.updateBlankPage(pageItemMap, layoutInfo); 237 settingsModel.setLayoutInfo(layoutInfo); 238 } 239 240 /** 241 * Delete form by cardId. 242 * 243 * @param {number} cardId. 244 */ 245 async deleteForm(cardId) { 246 Log.showDebug(TAG, 'deleteForm start'); 247 let gridLayoutInfo = { 248 layoutInfo: [] 249 }; 250 gridLayoutInfo = SettingsModel.getInstance().getLayoutInfo(); 251 const cardIndex = gridLayoutInfo.layoutInfo.findIndex(item => { 252 return item.typeId === CommonConstants.TYPE_CARD && item.cardId === cardId; 253 }); 254 if (cardIndex != CommonConstants.INVALID_VALUE) { 255 this.deleteFormById(cardId); 256 const page = gridLayoutInfo.layoutInfo[cardIndex].page; 257 gridLayoutInfo.layoutInfo.splice(cardIndex, 1); 258 let ret: boolean = this.mPageDesktopModel.deleteBlankPageFromLayoutInfo(gridLayoutInfo, page); 259 SettingsModel.getInstance().setLayoutInfo(gridLayoutInfo); 260 if(ret){ 261 const curPageIndex = this.mPageDesktopModel.getPageIndex(); 262 Log.showInfo(TAG, 'deleteForm' + curPageIndex); 263 this.mPageDesktopModel.setPageIndex(curPageIndex - 1); 264 } 265 } 266 const formInfoList: any = this.mFormListInfoCacheManager.getCache(KEY_FORM_LIST); 267 if (formInfoList === CommonConstants.INVALID_VALUE) { 268 return; 269 } 270 for(let i = 0; i < formInfoList.length; i++) { 271 if (formInfoList[i].cardId === cardId){ 272 formInfoList.splice(i, 1); 273 break; 274 } 275 } 276 if (formInfoList.length === 0) { 277 this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, null); 278 } else { 279 this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, formInfoList); 280 } 281 } 282 283 /** 284 * update page number if blank page is exist 285 * 286 * @param pageItemMap 287 * @param layoutInfo 288 */ 289 private updateBlankPage(pageItemMap, layoutInfo): void { 290 const blankPages = []; 291 for (let [page, count] of pageItemMap) { 292 if (count === 0) { 293 layoutInfo.layoutDescription.pageCount--; 294 blankPages.push(page); 295 } 296 } 297 for (let m = 0; m < layoutInfo.layoutInfo.length; m++) { 298 let pageMinus = 0; 299 for (let n = 0; n < blankPages.length; n++) { 300 if (layoutInfo.layoutInfo[m].page > blankPages[n]) { 301 pageMinus++; 302 } 303 } 304 if (pageMinus != 0) { 305 layoutInfo.layoutInfo[m].page = layoutInfo.layoutInfo[m].page - pageMinus; 306 } 307 } 308 } 309 310}