• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Prompt from '@ohos.promptAction';
17import {
18  Log,
19  Trace,
20  CheckEmptyUtils,
21  StyleConstants,
22  EventConstants,
23  CommonConstants,
24  FormManager,
25  BadgeManager,
26  windowManager,
27  layoutConfigManager,
28  BaseViewModel,
29  SettingsModelObserver,
30  FormListInfoCacheManager,
31  FormModel,
32  SettingsModel,
33  PageDesktopModel,
34  MenuInfo,
35  CardItemInfo,
36  localEventManager,
37  GridLayoutInfo,
38  LauncherDragItemInfo
39} from '@ohos/common';
40import { BigFolderModel } from '@ohos/bigfolder';
41import { FormDetailLayoutConfig } from '@ohos/form';
42import PageDesktopConstants from '../common/constants/PageDesktopConstants';
43import { PageDesktopGridStyleConfig } from '../common/PageDesktopGridStyleConfig';
44import formHost from '@ohos.app.form.formHost';
45import formInfoApi from '@ohos.app.form.formInfo';
46
47const TAG = 'PageDesktopViewModel';
48const KEY_APP_LIST = 'appListInfo';
49const KEY_FORM_LIST = 'formListInfo';
50
51export class PageDesktopViewModel extends BaseViewModel {
52  private readonly pageDesktopStyleConfig: PageDesktopGridStyleConfig = null;
53  private readonly formDetailLayoutConfig: FormDetailLayoutConfig = null;
54  private readonly mSettingsModel: SettingsModel;
55  private readonly mFolderModel: BigFolderModel;
56  private readonly mFormModel: FormModel;
57  private readonly mPageDesktopModel: PageDesktopModel;
58  private readonly mBadgeManager: BadgeManager;
59  private readonly mFormListInfoCacheManager: FormListInfoCacheManager;
60  private mBundleInfoList;
61  private mHideBundleInfoList = new Array<any>();
62  private mGridConfig;
63  private mGridAppsInfos;
64  private readonly mPageCoordinateData = {
65    gridXAxis: [],
66    gridYAxis: []
67  };
68  private isPad = false;
69  private isAddByDraggingFlag = false;
70  private desktopSwiperController: SwiperController;
71
72  async showFormManager(params) {
73    windowManager.createWindowWithName(windowManager.FORM_MANAGER_WINDOW_NAME, windowManager.RECENT_RANK);
74  }
75
76  setSwiperController(swiperController: SwiperController): void {
77    this.desktopSwiperController = swiperController;
78  }
79
80  showNext(): void {
81    this.desktopSwiperController?.showNext();
82  }
83
84  showPrevious(): void {
85    this.desktopSwiperController?.showPrevious();
86  }
87
88  private readonly mLocalEventListener = {
89    onReceiveEvent: (event, params) => {
90      Log.showDebug(TAG, `localEventListener receive event: ${event}, params: ${params}`);
91      switch (event) {
92        case EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD:
93          this.addToDesktop(params);
94          break;
95        case EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_DELETE:
96          this.deleteAppItem(params);
97          break;
98        case EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE:
99          this.getGridList();
100          break;
101        case EventConstants.EVENT_BADGE_UPDATE:
102          this.updateBadgeNumber(params);
103          break;
104        case EventConstants.EVENT_REQUEST_PAGEDESK_FORM_ITEM_ADD:
105          this.createCardToDeskTop(params);
106          break;
107        case EventConstants.EVENT_SMARTDOCK_INIT_FINISHED:
108          this.getGridList();
109          break;
110        case EventConstants.EVENT_REQUEST_PAGEDESK_REFRESH:
111          this.pagingFiltering();
112          break;
113        case EventConstants.EVENT_REQUEST_FORM_ITEM_VISIBLE:
114          this.notifyVisibleForms();
115          break;
116        default:
117          if (!this.isPad) {
118            Log.showDebug(TAG, 'localEventListener hideBundleInfoList!')
119            this.mHideBundleInfoList = params;
120            this.getGridList();
121          }
122          break;
123      }
124    }
125  };
126
127  /**
128   * Notify forms on current page become visible.
129   */
130  notifyVisibleForms(): void {
131    let pageIndex = this.mPageDesktopModel.getPageIndex();
132    let formList = [];
133    let items = this.mGridAppsInfos[pageIndex];
134    for (let i = 0; i < items.length; i++) {
135      if (items[i].typeId == CommonConstants.TYPE_CARD) {
136        formList.push(String(items[i].cardId));
137      }
138    }
139    if (formList.length > 0) {
140      try {
141        formHost.notifyVisibleForms(formList).then(() => {
142          Log.showInfo(TAG, 'formHost notifyVisibleForms success');
143        }).catch((error) => {
144          Log.showInfo(TAG, 'formHost notifyVisibleForms, error:' + JSON.stringify(error));
145        });
146      } catch(error) {
147        Log.showInfo(TAG, `catch err->${JSON.stringify(error)}`);
148      }
149    }
150  }
151
152  private readonly mSettingsChangeObserver: SettingsModelObserver = (event: number)=> {
153    this.mGridConfig = this.getGridConfig();
154    this.pagingFiltering();
155  };
156
157  private constructor() {
158    super();
159    this.mPageDesktopModel = PageDesktopModel.getInstance();
160    this.mFolderModel = BigFolderModel.getInstance();
161    this.mFormModel = FormModel.getInstance();
162    this.mSettingsModel = SettingsModel.getInstance();
163    this.mBadgeManager = BadgeManager.getInstance();
164    this.mFormListInfoCacheManager = FormListInfoCacheManager.getInstance();
165    this.mSettingsModel.forceReloadConfig();
166    this.mSettingsModel.addObserver(this.mSettingsChangeObserver);
167    this.onPageDesktopCreate();
168    this.mGridConfig = this.getGridConfig();
169    this.pageDesktopStyleConfig = layoutConfigManager.getStyleConfig(PageDesktopGridStyleConfig.APP_GRID_STYLE_CONFIG, PageDesktopConstants.FEATURE_NAME);
170    this.formDetailLayoutConfig = layoutConfigManager.getStyleConfig(FormDetailLayoutConfig.FORM_LAYOUT_INFO, PageDesktopConstants.FEATURE_NAME);
171  }
172
173  /**
174   * Obtains the PageDesktopViewModel instance.
175   *
176   * @return PageDesktopViewModel
177   */
178  static getInstance(): PageDesktopViewModel {
179    if (globalThis.PageDesktopViewModel == null) {
180      globalThis.PageDesktopViewModel = new PageDesktopViewModel();
181    }
182    return globalThis.PageDesktopViewModel;
183  }
184
185  /**
186   * Registering Listening Events.
187   */
188  private onPageDesktopCreate(): void {
189    this.mAppModel.registerAppListEvent();
190    this.mPageDesktopModel.registerPageDesktopItemAddEvent(this.mLocalEventListener);
191    this.mPageDesktopModel.registerPageDesktopBadgeUpdateEvent(this.mLocalEventListener);
192  }
193
194  /**
195   * Unregistering Listening Events.
196   */
197  private onPageDesktopDestroy(): void {
198    this.mAppModel.unregisterAppListEvent();
199    this.mPageDesktopModel.unregisterEventListener(this.mLocalEventListener);
200  }
201
202  /**
203   * Obtains the application list displayed on the desktop.
204   */
205  async getGridList() {
206    const appInfoList = await this.getAppList();
207    const bundleInfoListTemp = [];
208    this.appendAppData(appInfoList, bundleInfoListTemp);
209    const folderInfoList = await this.mFolderModel.getFolderList();
210    Log.showDebug(TAG, 'getAppList folderInfoList length: ' + folderInfoList.length);
211    this.appendFolderData(folderInfoList, bundleInfoListTemp);
212    let formInfoList: any = this.mFormListInfoCacheManager.getCache(KEY_FORM_LIST);
213    if (formInfoList == CommonConstants.INVALID_VALUE) {
214      formInfoList = await this.mFormModel.getAllFormsInfoFromRdb();
215      if (formInfoList && formInfoList.length > 0) {
216        this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, formInfoList);
217      }
218    }
219    this.appendFormData(formInfoList, bundleInfoListTemp);
220    this.mBundleInfoList = bundleInfoListTemp;
221    this.pagingFiltering();
222  }
223
224  async updateDesktopInfo(): Promise<void> {
225    await this.mAppModel.getAppListAsync();
226    this.getGridList();
227    AppStorage.setOrCreate('formRefresh', String(new Date()));
228  }
229
230  async updateForms(): Promise<void> {
231    Log.showInfo(TAG, 'updateForms start');
232    let allFormsInfo: CardItemInfo[] = await this.mFormModel.getAllFormsInfoFromRdb();
233    if (allFormsInfo.length) {
234      for (const { cardId } of allFormsInfo) {
235        if (CheckEmptyUtils.isEmpty(cardId)) {
236          continue;
237        }
238        Log.showInfo(TAG, `updateForms cardId: ${cardId}`);
239        this.requestForm(String(cardId));
240      }
241    }
242  }
243
244  requestForm(formId: string): void {
245    Log.showInfo(TAG, `formHost requestForm ${formId}`);
246    try {
247      formHost.requestForm(formId).then(() => {
248        Log.showInfo(TAG, 'formHost requestForm success');
249      }).catch((error) => {
250        Log.showError(TAG, `formHost requestForm error, code: ${error.code}, message: ${error.message}`);
251      });
252    } catch (err) {
253      Log.showError(TAG, `formHost requestForm fail, err->${JSON.stringify(err)}`);
254    }
255  }
256
257  private async getAppList() {
258    Log.showInfo(TAG, 'getAppList start');
259
260    // get total app from system
261    const totalAppInfoList = await this.mAppModel.getAppList();
262
263    // get pageDesktop app from config
264    let pageDesktopInfo = this.mSettingsModel.getAppListInfo();
265
266    // get from config empty then init pageDesktop app
267    if (!this.mSettingsModel.isAppListInfoExist() && this.ifInfoIsNull(pageDesktopInfo)) {
268      for (const appInfo of totalAppInfoList) {
269        pageDesktopInfo.push(appInfo);
270      }
271    } else {
272      // remove uninstalled app
273      pageDesktopInfo = pageDesktopInfo.filter(item => {
274        for (const appInfo of totalAppInfoList) {
275          if (item.keyName == appInfo.keyName) {
276            item.appName = appInfo.appName;
277            item.appIconId = appInfo.appIconId;
278            return true;
279          }
280        }
281        return false;
282      });
283    }
284
285    // product phone logic
286    if (!this.isPad) {
287      this.addNewInstalledInfo(totalAppInfoList, pageDesktopInfo);
288      this.removeBottomBarInfo(pageDesktopInfo);
289    }
290    this.removeFolderInfo(pageDesktopInfo);
291
292    // update pageDesktop app config
293    this.mSettingsModel.setAppListInfo(pageDesktopInfo);
294    AppStorage.setOrCreate('isDesktopLoadFinished', true);
295    return pageDesktopInfo;
296  }
297
298  /**
299   * delete app in pageDesktop
300   *
301   * @param abilityName
302   * @param bundleName
303   */
304  deleteAppItem(appItem: {bundleName: string | undefined, keyName: string | undefined}) {
305    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
306    Log.showDebug(TAG, `deleteAppItem appItem: ${JSON.stringify(appItem)}`);
307    if (appItem.bundleName) {
308      this.mBundleInfoList = this.mBundleInfoList.filter(item => item.bundleName !== appItem.bundleName);
309    } else if(appItem.keyName) {
310      this.mBundleInfoList = this.mBundleInfoList.filter(item => item.keyName !== appItem.keyName);
311    }
312    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
313
314    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
315    const layoutInfo = gridLayoutInfo.layoutInfo;
316    for (let i = 0; i < layoutInfo.length; i++) {
317      if (layoutInfo[i].typeId == CommonConstants.TYPE_APP &&
318      (layoutInfo[i].bundleName == appItem.bundleName || layoutInfo[i].keyName == appItem.keyName)) {
319        const page = layoutInfo[i].page;
320        gridLayoutInfo.layoutInfo.splice(i, 1);
321        let ret: boolean = this.mPageDesktopModel.deleteBlankPageFromLayoutInfo(gridLayoutInfo, page);
322        this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
323        if(ret){
324          const curPageIndex = this.mPageDesktopModel.getPageIndex();
325          Log.showInfo(TAG, 'deleteAppItem' + curPageIndex);
326          this.mPageDesktopModel.setPageIndex(curPageIndex - 1);
327        }
328        break;
329      }
330    }
331    this.getGridList();
332  }
333
334  /**
335   * add app to pageDesktop
336   *
337   * @param appInfo
338   */
339  addToDesktop(appInfo) {
340    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
341    Log.showDebug(TAG, `addToDesktop keyName: ${appInfo.keyName} mBundleInfoList length: ${this.mBundleInfoList.length}`);
342    for (let i = 0; i < this.mBundleInfoList.length; i++) {
343      if (this.mBundleInfoList[i].keyName === appInfo.keyName) {
344        Prompt.showToast({
345          message: $r('app.string.duplicate_add')
346        });
347        return;
348      }
349    }
350
351    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
352
353    // Check if app is in folder
354    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
355      if (gridLayoutInfo.layoutInfo[i].typeId === CommonConstants.TYPE_FOLDER) {
356        const appIndex = gridLayoutInfo.layoutInfo[i].layoutInfo[0].findIndex(item => {
357          return item.keyName === appInfo.keyName;
358        })
359        if (appIndex != CommonConstants.INVALID_VALUE) {
360          Prompt.showToast({
361            message: $r('app.string.duplicate_add')
362          });
363          return;
364        }
365      }
366    }
367
368    this.mBundleInfoList.push(appInfo);
369    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
370    this.getGridList();
371  }
372
373  /**
374   * add form to pageDesktop
375   *
376   * @param appInfo
377   */
378  addFormToDesktop(formInfo) {
379    Log.showInfo(TAG, 'addFormToDesktop');
380    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
381    switch(formInfo.dimension) {
382      case formInfoApi.FormDimension.Dimension_1_2:
383        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension1X2.row;
384        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension1X2.column;
385        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension1X2.area;
386        break;
387      case formInfoApi.FormDimension.Dimension_2_2:
388        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X2.row;
389        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X2.column;
390        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X2.area;
391        break;
392      case formInfoApi.FormDimension.Dimension_2_4:
393        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X4.row;
394        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X4.column;
395        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension2X4.area;
396        break;
397      case formInfoApi.FormDimension.Dimension_4_4:
398        formInfo.row = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension4X4.row;
399        formInfo.column = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension4X4.column;
400        formInfo.area = this.formDetailLayoutConfig.getFormLayoutInfo().formLayoutDimension4X4.area;
401        break;
402      default:
403        break;
404    }
405    this.mBundleInfoList.push(formInfo);
406    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
407    this.getGridList();
408  }
409
410  /**
411   * update badge in desktop
412   *
413   * @param badgeInfo
414   */
415  updateBadgeNumber(badgeInfo) {
416    this.mBundleInfoList = this.mSettingsModel.getAppListInfo();
417
418    let appInfo = this.mBundleInfoList.find(item => {
419      return item.bundleName == badgeInfo.bundleName;
420    });
421    if (!this.ifInfoIsNull(appInfo)) {
422      Log.showDebug(TAG, `updateBadgeNumber bundleName: ${badgeInfo.bundleName}`);
423      appInfo.badgeNumber = badgeInfo.badgeNumber;
424      this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
425      this.getGridList();
426    } else {
427      Log.showDebug(TAG, 'updateBadgeNumber appInfo is null ');
428      const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
429      const layoutInfo = gridLayoutInfo.layoutInfo;
430      let hasFound = false;
431      for (let i = 0; i < layoutInfo.length; i++) {
432        if (hasFound) {
433          break;
434        }
435        if (layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER && !hasFound) {
436          for (let j = 0; j < layoutInfo[i].layoutInfo.length; j++) {
437            appInfo = layoutInfo[i].layoutInfo[j].find(item => {
438              return item.bundleName == badgeInfo.bundleName;
439            });
440
441            if (!this.ifInfoIsNull(appInfo)) {
442              hasFound = true;
443              appInfo.badgeNumber = badgeInfo.badgeNumber;
444              break;
445            }
446          }
447          layoutInfo[i].badgeNumber = this.getFolderBadgeNumber(layoutInfo[i]);
448        }
449      }
450      if (hasFound) {
451        this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
452        this.getGridList();
453      }
454    }
455  }
456
457  private getFolderBadgeNumber(folderInfo) {
458    let bidfolderBadgeNumber: number = 0;
459    let layoutInfo: [[]] = folderInfo.layoutInfo;
460    for (var i = 0; i < layoutInfo.length; i++) {
461      layoutInfo[i].forEach((item: any) => {
462        if (item.badgeNumber && item.badgeNumber > 0) {
463          bidfolderBadgeNumber = bidfolderBadgeNumber + item.badgeNumber;
464        }
465      });
466    }
467    return bidfolderBadgeNumber;
468  }
469
470  /**
471   * add app to pageDesktop by dragging
472   *
473   * @param appInfo
474   */
475  addToDesktopByDraging(appInfo) {
476    Log.showDebug(TAG, `addToDesktopByDraging bundleName: ${appInfo.bundleName}`);
477    this.mGridConfig = this.mSettingsModel.getGridConfig();
478    for (let i = 0; i < this.mBundleInfoList.length; i++) {
479      if (this.mBundleInfoList[i].bundleName === appInfo.bundleName) {
480        Prompt.showToast({
481          message: $r('app.string.duplicate_add')
482        });
483        return;
484      }
485    }
486    this.mBundleInfoList.push(appInfo);
487    this.mSettingsModel.setAppListInfo(this.mBundleInfoList);
488    this.getGridList();
489  }
490
491  /**
492   * add app to dock
493   *
494   * @param appInfo
495   */
496  addToDock(appInfo) {
497    this.mPageDesktopModel.sendDockItemChangeEvent(appInfo);
498  }
499
500  private appendAppData(appInfoList, bundleInfoList) {
501    for (let i = 0; i < appInfoList.length; i++) {
502      if (this.isInHideAppList(appInfoList[i])) {
503        continue;
504      }
505      appInfoList[i].typeId = CommonConstants.TYPE_APP;
506      appInfoList[i].area = [1, 1];
507      bundleInfoList.push(appInfoList[i]);
508    }
509  }
510
511  private isInHideAppList(appInfo): boolean {
512    for (const hideInfo of this.mHideBundleInfoList) {
513      if (appInfo.keyName == hideInfo.keyName) {
514        return true;
515      }
516    }
517    return false;
518  }
519
520  private appendFolderData(folderInfoList, bundleInfoList) {
521    for (let i = 0; i < folderInfoList.length; i++) {
522      for (let j = 0; j < folderInfoList[i].layoutInfo.length; j++) {
523        for (let k = 0; k < folderInfoList[i].layoutInfo[j].length; k++) {
524          const appIndex = bundleInfoList.findIndex(item => {
525            return item.keyName === folderInfoList[i].layoutInfo[j][k].keyName;
526          });
527          if (appIndex != CommonConstants.INVALID_VALUE) {
528            bundleInfoList.splice(appIndex, 1);
529          }
530        }
531      }
532    }
533  }
534
535  private appendFormData(formInfoList, bundleInfoList) {
536    for (let i = 0; i < formInfoList.length; i++) {
537      formInfoList[i].typeId = CommonConstants.TYPE_CARD;
538      bundleInfoList.push(formInfoList[i]);
539    }
540  }
541
542  /**
543   * Obtains Grid Configuration.
544   */
545  getGridConfig() {
546    return this.mSettingsModel.getGridConfig();
547  }
548
549  /**
550   * refresh page
551   */
552  pagingFiltering() {
553    const appInfo = {
554      appGridInfo: []
555    };
556    const appListInfo = [];
557    const info = this.getAndSetLayoutInfo();
558    const layoutInfo = info.layoutInfo;
559    for (let i = 0; i < layoutInfo.length; i++) {
560      if (layoutInfo[i].typeId == CommonConstants.TYPE_APP) {
561        for (let j = 0; j < this.mBundleInfoList.length; j++) {
562          if (layoutInfo[i].keyName == this.mBundleInfoList[j].keyName
563          && layoutInfo[i].typeId == this.mBundleInfoList[j].typeId) {
564            this.mBundleInfoList[j].area = layoutInfo[i].area;
565            this.mBundleInfoList[j].page = layoutInfo[i].page;
566            this.mBundleInfoList[j].row = layoutInfo[i].row;
567            this.mBundleInfoList[j].column = layoutInfo[i].column;
568            this.mBundleInfoList[j].x = 0;
569            appListInfo.push(this.mBundleInfoList[j]);
570          }
571        }
572      } else if (layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
573        appListInfo.push(layoutInfo[i]);
574      } else if (layoutInfo[i].typeId == CommonConstants.TYPE_CARD) {
575        for (let j = 0; j < this.mBundleInfoList.length; j++) {
576          if (layoutInfo[i].cardId == this.mBundleInfoList[j].cardId
577          && layoutInfo[i].typeId == this.mBundleInfoList[j].typeId) {
578            this.mBundleInfoList[j].cardId = layoutInfo[i].cardId;
579            this.mBundleInfoList[j].area = layoutInfo[i].area;
580            this.mBundleInfoList[j].page = layoutInfo[i].page;
581            this.mBundleInfoList[j].row = layoutInfo[i].row;
582            this.mBundleInfoList[j].column = layoutInfo[i].column;
583            this.mBundleInfoList[j].x = 0;
584            appListInfo.push(this.mBundleInfoList[j]);
585          }
586        }
587      }
588    }
589    appInfo.appGridInfo = this.integrateSwiper(appListInfo);
590    Log.showInfo(TAG, 'pagingFiltering appListInfo length:' + appListInfo.length);
591    AppStorage.setOrCreate('selectDesktopAppItem', '');
592    AppStorage.setOrCreate(KEY_APP_LIST, appInfo);
593  }
594
595  private integrateSwiper(list) {
596    let gridAppsInfos = [];
597    const allPageCount = this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount;
598    let max = allPageCount;
599    for (let i = 0;i < list.length; i++) {
600      if (max <= list[i].page + 1) {
601        max = list[i].page + 1;
602      }
603    }
604
605    for (let i = 0;i < max; i++) {
606      gridAppsInfos.push([]);
607    }
608
609    for (let i = 0;i < list.length; i++) {
610      gridAppsInfos[list[i].page].push(list[i]);
611    }
612
613    //If the workspace has no applications,
614    // it needs to be initialized to [].
615    if (gridAppsInfos.length == 0) {
616      gridAppsInfos.push([]);
617    }
618
619    this.mGridAppsInfos = gridAppsInfos;
620    return gridAppsInfos;
621  }
622
623  private getAndSetLayoutInfo() {
624    let info = this.mSettingsModel.getLayoutInfo();
625    const isLegal = this.ifLayoutRationality(info);
626    if (isLegal) {
627      info = this.updateLayoutInfo(info);
628    } else {
629      info = this.updateLayoutInfo(this.createNewLayoutInfo());
630    }
631    this.mSettingsModel.setLayoutInfo(info);
632    return info;
633  }
634
635  private ifLayoutRationality(info) {
636    //verify whether the info is null.
637    if (this.ifInfoIsNull(info)) {
638      return false;
639    }
640    const layoutDescription = info.layoutDescription;
641
642    //verify whether the layoutDescription is different.
643    this.mGridConfig = this.getGridConfig();
644    const column = this.mGridConfig.column;
645    const row = this.mGridConfig.row;
646    if (this.ifDescriptionIsDifferent(layoutDescription, row, column)) {
647      return false;
648    }
649
650    //verify whether the layoutInfo's row and column is more than standard.
651    if (this.ifColumnOrRowAreBigger(info.layoutInfo, row, column)) {
652      return false;
653    }
654
655    //verify whether the layoutInfo's position is duplicated.
656    if (this.ifDuplicatePosition(info.layoutInfo)) {
657      return false;
658    }
659    //verify whether the layoutInfo's keyName is duplicated.
660    if (this.ifDuplicateKeyName(info.layoutInfo)) {
661      return false;
662    }
663    return true;
664  };
665
666  private ifInfoIsNull(info) {
667    if (info == undefined || info == '' || JSON.stringify(info) == '{}' || info == null) {
668      return true;
669    }
670    return false;
671  }
672
673  private ifDescriptionIsDifferent(layoutDescription, row, column) {
674    if (row != layoutDescription.row || column != layoutDescription.column) {
675      return true;
676    }
677    return false;
678  }
679
680  private ifColumnOrRowAreBigger(layoutInfo, row, column) {
681    for (let i = 0; i < layoutInfo.length; i++) {
682      //column or row are bigger than legal num
683      if (layoutInfo[i].column >= column || layoutInfo[i].row >= row) {
684        return true;
685      }
686    }
687    return false;
688  }
689
690  private ifDuplicatePosition(layoutInfo) {
691    const mPositionInfo = [];
692    for (let i = 0; i < layoutInfo.length; i++) {
693      for(let j = 0; j < layoutInfo[i].area[1]; j++){
694        for(let k = 0; k < layoutInfo[i].area[0]; k++){
695          const position = [];
696          position[0] = layoutInfo[i].page;
697          position[1] = layoutInfo[i].row + j;
698          position[2] = layoutInfo[i].column + k;
699          mPositionInfo.push(position);
700        }
701      }
702    }
703    for (let i = 0; i < mPositionInfo.length; i++) {
704      for (let j = mPositionInfo.length - 1; j > 0 && j > i; j--) {
705        if (mPositionInfo[i][0] == mPositionInfo[j][0] && mPositionInfo[i][1] == mPositionInfo[j][1] && mPositionInfo[i][2] == mPositionInfo[j][2]) {
706          return true;
707        }
708
709      }
710    }
711    return false;
712  }
713
714  private ifDuplicateKeyName(layoutInfo) {
715    const count = [];
716    for (let i = 0; i < layoutInfo.length; i++) {
717      if (CheckEmptyUtils.isEmpty(count[layoutInfo[i].keyName])) {
718        count[layoutInfo[i].keyName] = 0;
719      } else if (layoutInfo[i].typeId == CommonConstants.TYPE_APP) {
720        return true;
721      }
722    }
723    return false;
724  }
725
726  private updateLayoutInfo(info) {
727    let layoutInfo = info.layoutInfo;
728    this.mGridConfig = this.getGridConfig();
729    Log.showDebug(TAG, 'updateLayoutInfo mGridConfig:' + JSON.stringify(this.mGridConfig));
730    info.layoutDescription.row = this.mGridConfig.row;
731    info.layoutDescription.column = this.mGridConfig.column;
732    const newApp = [];
733    //Detect newly installed apps
734    for (const i in this.mBundleInfoList) {
735      let sign = false;
736      for (const j in layoutInfo) {
737        if (this.mBundleInfoList[i].typeId == layoutInfo[j].typeId
738        && this.mBundleInfoList[i].typeId == CommonConstants.TYPE_APP
739        && this.mBundleInfoList[i].keyName == layoutInfo[j].keyName) {
740          layoutInfo[j].badgeNumber = this.mBundleInfoList[i].badgeNumber;
741          sign = true;
742          break;
743        }
744      }
745      if (!sign) {
746        newApp.push(this.mBundleInfoList[i]);
747      }
748    }
749
750    //Detect uninstalled apps, remove all apps which have same bundleName when one app is uninstalled
751    layoutInfo = layoutInfo.filter(item => {
752      if (item.typeId == CommonConstants.TYPE_FOLDER || item.typeId == CommonConstants.TYPE_CARD) {
753        return true;
754      }
755      for (const bundleInfo of this.mBundleInfoList) {
756        if (item.keyName == bundleInfo.keyName) {
757          return true;
758        }
759      }
760      return false;
761    })
762    info.layoutInfo = layoutInfo;
763
764    // calculate the layout of new apps
765    for (let i = 0; i < newApp.length; i++) {
766      if (newApp[i].typeId == CommonConstants.TYPE_APP) {
767        this.mPageDesktopModel.updateAppItemLayoutInfo(info, newApp[i]);
768      }
769    }
770    let infoOld = this.mSettingsModel.getLayoutInfo();
771    for (const item of infoOld.layoutInfo) {
772      if (item.typeId == CommonConstants.TYPE_APP) {
773        for (const infoNew of info.layoutInfo) {
774          if (item.keyName == infoNew.keyName) {
775            infoNew.page = item.page;
776          }
777        }
778      }
779    }
780    return info;
781  }
782
783  private createNewInfo() {
784    this.mGridConfig = this.getGridConfig();
785    const column = this.mGridConfig.column;
786    const row = this.mGridConfig.row;
787    const layoutNum = this.mBundleInfoList.length;
788    const maxPerPage = column * row;
789    const pageNum = Math.ceil(layoutNum / maxPerPage);
790    const newLayoutInfo: GridLayoutInfo = {
791      layoutDescription: undefined,
792      layoutInfo: []
793    };
794    newLayoutInfo.layoutDescription = {
795      'pageCount': pageNum,
796      'row': row,
797      'column': column,
798    };
799    newLayoutInfo.layoutInfo = [];
800    return newLayoutInfo;
801  }
802
803  private createNewLayoutInfo() {
804    const info = this.mSettingsModel.getLayoutInfo();
805    this.mGridConfig = this.getGridConfig();
806    const column = this.mGridConfig.column;
807    const row = this.mGridConfig.row;
808    const layoutNum = info.layoutInfo.length;
809    const maxPerPage = column * row;
810    const pageNum = Math.ceil(layoutNum / maxPerPage);
811    const newLayoutInfo: GridLayoutInfo = {
812      layoutDescription: undefined,
813      layoutInfo: []
814    };
815    newLayoutInfo.layoutDescription = {
816      'pageCount': info.layoutDescription.pageCount,
817      'row': row,
818      'column': column
819    };
820    if (AppStorage.has('isPortrait') && AppStorage.get('isPortrait')) {
821      let cardInfoHorizontal: any[] = [];
822      for (let i = 0; i < info.layoutInfo.length; i++) {
823        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
824          let tt = info.layoutInfo[i].column
825          info.layoutInfo[i].column = info.layoutInfo[i].row;
826          info.layoutInfo[i].row = tt;
827          newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
828        }
829      }
830
831      for (let i = 0; i < info.layoutInfo.length; i++) {
832        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_CARD) {
833          if (info.layoutInfo[i].area[0] == info.layoutInfo[i].area[1]) {
834            let tt = info.layoutInfo[i].column
835            info.layoutInfo[i].column = info.layoutInfo[i].row;
836            info.layoutInfo[i].row = tt;
837            newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
838          } else {
839            cardInfoHorizontal.push(JSON.stringify(info.layoutInfo[i]));
840            this.mPageDesktopModel.updatePageDesktopLayoutInfo(newLayoutInfo, info.layoutInfo[i]);
841            newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
842          }
843        }
844      }
845      AppStorage.setOrCreate('isPortraitCard', cardInfoHorizontal);
846    }
847
848    if (AppStorage.has('isPortrait') && !AppStorage.get('isPortrait')) {
849      for (let i = 0; i < info.layoutInfo.length; i++) {
850        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
851          let tt = info.layoutInfo[i].column
852          info.layoutInfo[i].column = info.layoutInfo[i].row;
853          info.layoutInfo[i].row = tt;
854          newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
855        }
856      }
857
858      for (let i = 0; i < info.layoutInfo.length; i++) {
859        if (info.layoutInfo[i].typeId == CommonConstants.TYPE_CARD) {
860          if (info.layoutInfo[i].area[0] == info.layoutInfo[i].area[1]) {
861            let tt = info.layoutInfo[i].column
862            info.layoutInfo[i].column = info.layoutInfo[i].row;
863            info.layoutInfo[i].row = tt;
864            newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
865          } else {
866            let cardInfoOld: [] = AppStorage.get('isPortraitCard');
867            Log.showInfo(TAG, 'cardInfoOld:' + JSON.stringify(cardInfoOld));
868            if (!cardInfoOld.find(item => JSON.parse(item).cardId === info.layoutInfo[i].cardId)) {
869              this.mPageDesktopModel.updatePageDesktopLayoutInfo(newLayoutInfo, info.layoutInfo[i]);
870              newLayoutInfo.layoutInfo.push(info.layoutInfo[i]);
871            }
872            for (let index = 0; index < cardInfoOld.length; index++) {
873              if (!newLayoutInfo.layoutInfo.find(item => item.cardId == JSON.parse(cardInfoOld[index]).cardId)) {
874                newLayoutInfo.layoutInfo.push(JSON.parse(cardInfoOld[index]));
875              }
876            }
877          }
878        }
879      }
880    }
881
882    if (!AppStorage.has('isPortrait')) {
883      newLayoutInfo.layoutDescription = {
884        'pageCount': pageNum,
885        'row': row,
886        'column': column
887      };
888      newLayoutInfo.layoutInfo = [];
889    }
890
891    return newLayoutInfo;
892  }
893
894  regroupDataAppListChange(callbackList) {
895    this.getGridList();
896  }
897
898  /**
899   * Open the app.
900   *
901   * @param abilityName
902   * @param bundleName
903   */
904  openApplication(abilityName: string, bundleName: string, moduleName: string): void {
905    this.jumpTo(abilityName, bundleName, moduleName);
906  }
907
908  /**
909   * Open Settings.
910   */
911  intoSetting(): void {
912    Log.showInfo(TAG, 'intoSetting');
913    this.jumpToSetting();
914  }
915
916  /**
917   * Get strings for addBlankPageButton.
918   *
919   * @return {string} AddBlankPageButton Strings.
920   */
921  getBlankPageBtnStr() {
922    return this.isBlankPage() ? $r('app.string.delete_blank_page') : $r('app.string.add_blank_page');
923  }
924
925  /**
926   * Get strings for deleteBlankPageButton.
927   *
928   * @return {string} AddBlankPageButton Strings.
929   */
930  getBlankPageBtnIcon() {
931    return this.isBlankPage() ? '/common/pics/ic_public_delete.svg' : '/common/pics/ic_public_add_black.svg';
932  }
933
934  isBlankPage(): boolean {
935    const curPageIndex = this.mPageDesktopModel.getPageIndex();
936    // 当且仅当只有一个页面时,菜单项只允许添加
937    if (this.getGridPageCount() <= 1) {
938      return false;
939    }
940    if (CheckEmptyUtils.isEmpty(this.mGridAppsInfos) || CheckEmptyUtils.isEmpty(this.mGridAppsInfos[curPageIndex])
941    || CheckEmptyUtils.isEmpty(this.mGridAppsInfos[curPageIndex].length)) {
942      return true;
943    }
944    if (this.mGridAppsInfos[curPageIndex].length === 0) {
945      return true;
946    }
947    return false;
948  }
949
950  /**
951   * Add or delete the chosen blank page.
952   */
953  addOrDeleteBlankPage(): void {
954    if (this.isBlankPage()) {
955      this.deleteBlankPage();
956    } else {
957      this.addBlankPage(false);
958    }
959  }
960
961  /**
962   * Add a blank page.
963   *
964   * @param {boolean} isAddByDrag
965   */
966  addBlankPage(isAddByDrag: boolean): void {
967    this.mPageDesktopModel.setAddByDragging(isAddByDrag);
968    const allPageCount = this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount + 1;
969    this.setGridPageCount(allPageCount);
970    this.pagingFiltering();
971    this.mPageDesktopModel.setPageIndex(allPageCount - 1);
972  }
973
974  /**
975   * Get pageCount.
976   *
977   * @return {number} PageCount.
978   */
979  /**
980   * Get pageCount.
981   *
982   * @return {number} PageCount.
983   */
984  getGridPageCount(): number {
985    return this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount;
986  }
987
988  /**
989   * Set pageCount.
990   *
991   * @param {number} pageCount - PageCount.
992   */
993  private setGridPageCount(pageCount: number): void {
994    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
995    gridLayoutInfo.layoutDescription.pageCount = pageCount;
996    this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
997  }
998
999  /**
1000   * Delete the chosen blank page.
1001   */
1002  private deleteBlankPage(): void {
1003    const curPageIndex = this.mPageDesktopModel.getPageIndex();
1004    this.deleteGridPage(curPageIndex);
1005    if (curPageIndex === 0) {
1006      this.mPageDesktopModel.setPageIndex(curPageIndex);
1007    } else {
1008      this.mPageDesktopModel.setPageIndex(curPageIndex - 1);
1009    }
1010    this.setGridPageCount(this.mSettingsModel.getLayoutInfo().layoutDescription.pageCount - 1);
1011    this.pagingFiltering();
1012  }
1013
1014  /**
1015   * Delete blank page.
1016   *
1017   * @param {number} pageIndex - Index of the page which is to be deleted.
1018   */
1019  private deleteGridPage(pageIndex: number): void {
1020    const info = this.mSettingsModel.getLayoutInfo();
1021    const layoutInfo = info.layoutInfo;
1022    for (const element of layoutInfo) {
1023      if (element.page > pageIndex) {
1024        element.page = element.page - 1;
1025      }
1026    }
1027    info.layoutInfo = layoutInfo;
1028    this.mSettingsModel.setLayoutInfo(info);
1029  }
1030
1031  /**
1032   * Set device type.
1033   *
1034   * @param EType: Device type
1035   */
1036  setDevice(EType): void {
1037    this.mSettingsModel.setDevice(EType);
1038    this.isPad = EType === CommonConstants.PAD_DEVICE_TYPE;
1039  }
1040
1041  /**
1042   * Get device type.
1043   */
1044  getDevice(): boolean {
1045    return this.isPad;
1046  }
1047
1048  buildMenuInfoList(appInfo, dialog, formDialog?, folderCallback?, openClickCallback?): MenuInfo[] {
1049    let menuInfoList = new Array<MenuInfo>();
1050    const shortcutInfo: any = this.mAppModel.getShortcutInfo(appInfo.bundleName);
1051    if (shortcutInfo) {
1052      let menu: MenuInfo | null = null;
1053      shortcutInfo.forEach((value) => {
1054        menu = new MenuInfo();
1055        menu.menuType = CommonConstants.MENU_TYPE_DYNAMIC;
1056        menu.menuImgSrc = value.icon;
1057        menu.menuText = value.label;
1058        menu.shortcutIconId = value.iconId;
1059        menu.shortcutLabelId =  value.labelId;
1060        menu.bundleName = value.bundleName;
1061        menu.moduleName = value.moduleName;
1062        menu.onMenuClick = () => {
1063          Trace.start(Trace.CORE_METHOD_START_APP_ANIMATION);
1064          if (openClickCallback) {
1065            openClickCallback();
1066          }
1067          if (AppStorage.get('openFolderStatus') != 0) {
1068            AppStorage.setOrCreate('openFolderStatus', 0);
1069          }
1070          this.jumpTo(value.wants[0].targetClass, value.wants[0].targetBundle, value.wants[0].targetModule);
1071        };
1072        value.bundleName == appInfo.bundleName && value.moduleName == appInfo.moduleName && menuInfoList.push(menu);
1073      });
1074    }
1075
1076    let open = new MenuInfo();
1077    open.menuType = CommonConstants.MENU_TYPE_FIXED;
1078    open.menuImgSrc = '/common/pics/ic_public_add_norm.svg';
1079    open.menuText = $r('app.string.app_menu_open');
1080    open.onMenuClick = () => {
1081      if (AppStorage.get('openFolderStatus') != 0 && AppStorage.get('deviceType') === CommonConstants.PAD_DEVICE_TYPE) {
1082        AppStorage.setOrCreate('openFolderStatus', 0);
1083      }
1084      this.setStartAppInfo()
1085      this.jumpTo(appInfo.abilityName, appInfo.bundleName, appInfo.moduleName);
1086    };
1087    menuInfoList.push(open);
1088
1089    const formInfoList = this.mFormModel.getAppItemFormInfo(appInfo.bundleName, appInfo.moduleName);
1090    if (!CheckEmptyUtils.isEmptyArr(formInfoList)) {
1091      let addFormToDeskTopMenu = new MenuInfo();
1092      addFormToDeskTopMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1093      addFormToDeskTopMenu.menuImgSrc = '/common/pics/ic_public_app.svg';
1094      addFormToDeskTopMenu.menuText = $r('app.string.add_form_to_desktop');
1095      addFormToDeskTopMenu.onMenuClick = () => {
1096        Log.showDebug(TAG, 'Launcher click menu item into add form to desktop view');
1097        const appName = this.getAppName(appInfo.appLabelId + appInfo.bundleName + appInfo.moduleName);
1098        if (appName != null) {
1099          appInfo.appName = appName;
1100        }
1101        AppStorage.setOrCreate('formAppInfo', appInfo);
1102        if (!this.isPad) {
1103          this.showFormManager(appInfo);
1104        } else {
1105          formDialog.open();
1106        }
1107      };
1108      menuInfoList.push(addFormToDeskTopMenu);
1109
1110      let formCenterMenu: MenuInfo = new MenuInfo();
1111      formCenterMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1112      formCenterMenu.menuImgSrc = '/common/pics/ic_form_center.svg';
1113      formCenterMenu.menuText = $r('app.string.form_center');
1114      formCenterMenu.onMenuClick = (): void => {
1115        Log.showInfo(TAG, 'Launcher click menu into form center view.');
1116        if (!this.isPad) {
1117          windowManager.createWindowWithName(windowManager.FORM_SERVICE_WINDOW_NAME, windowManager.RECENT_RANK);
1118        }
1119      };
1120      menuInfoList.push(formCenterMenu);
1121    }
1122
1123    if (this.isPad) {
1124      const addToDockMenu = new MenuInfo();
1125      addToDockMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1126      addToDockMenu.menuImgSrc = '/common/pics/ic_public_copy.svg';
1127      addToDockMenu.menuText = $r('app.string.app_center_menu_add_dock');
1128      addToDockMenu.onMenuClick = () => {
1129        Log.showDebug(TAG, 'Launcher click menu item add to dock');
1130        const appName = this.getAppName(appInfo.appLabelId + appInfo.bundleName + appInfo.moduleName);
1131        if (appName != null) {
1132          appInfo.appName = appName;
1133        }
1134        this.addToDock(appInfo);
1135      };
1136      menuInfoList.push(addToDockMenu);
1137    }
1138
1139    if (folderCallback) {
1140      const moveOutMenu = new MenuInfo();
1141      moveOutMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1142      moveOutMenu.menuImgSrc = '/common/pics/ic_public_remove.svg';
1143      moveOutMenu.menuText = $r('app.string.remove_app_from_folder');
1144      moveOutMenu.onMenuClick = () => {
1145        Log.showDebug(TAG, 'Launcher click menu item remove app from folder');
1146        // remove app from folder
1147        folderCallback(appInfo);
1148      };
1149      menuInfoList.push(moveOutMenu);
1150    }
1151
1152    const uninstallMenu = new MenuInfo();
1153    uninstallMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1154    uninstallMenu.menuImgSrc = this.isPad ? '/common/pics/ic_public_remove.svg' : '/common/pics/ic_public_delete.svg';
1155    uninstallMenu.menuText = this.isPad ?  $r('app.string.delete_app') : $r('app.string.uninstall');
1156    uninstallMenu.onMenuClick = () => {
1157      Log.showDebug(TAG, 'Launcher click menu item uninstall');
1158      const appName = this.getAppName(appInfo.appLabelId + appInfo.bundleName + appInfo.moduleName);
1159      if (appName != null) {
1160        appInfo.appName = appName;
1161      }
1162      AppStorage.setOrCreate('uninstallAppInfo', appInfo);
1163      dialog.open();
1164    };
1165    uninstallMenu.menuEnabled = appInfo.isUninstallAble;
1166    menuInfoList.push(uninstallMenu);
1167    return menuInfoList;
1168  }
1169
1170  buildCardMenuInfoList(formInfo, dialog, formDialog): MenuInfo[] {
1171    const menuInfoList = new Array<MenuInfo>();
1172    if (!this.ifStringIsNull(formInfo.formConfigAbility)
1173    && formInfo.formConfigAbility.startsWith(CommonConstants.FORM_CONFIG_ABILITY_PREFIX, 0)) {
1174      const editForm = new MenuInfo();
1175      editForm.menuType = CommonConstants.MENU_TYPE_FIXED;
1176      editForm.menuImgSrc = '/common/pics/ic_public_edit.svg';
1177      editForm.menuText = $r('app.string.form_edit');
1178      editForm.onMenuClick = () => {
1179        Log.showDebug(TAG, `Launcher click menu item into form edit view:${formInfo.formConfigAbility}`);
1180        const abilityName = formInfo.formConfigAbility.slice(CommonConstants.FORM_CONFIG_ABILITY_PREFIX.length);
1181        this.jumpToForm(abilityName, formInfo.bundleName, formInfo.moduleName, formInfo.cardId);
1182      };
1183      menuInfoList.push(editForm);
1184    }
1185    const addFormToDeskTopMenu = new MenuInfo();
1186    addFormToDeskTopMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1187    addFormToDeskTopMenu.menuImgSrc = '/common/pics/ic_desktop_servicewidgets.svg';
1188    addFormToDeskTopMenu.menuText = $r('app.string.add_form_to_desktop_more');
1189    addFormToDeskTopMenu.onMenuClick = () => {
1190      Log.showDebug(TAG, 'Launcher click menu item into add form to desktop view');
1191      const appName = this.getAppName(formInfo.appLabelId + formInfo.bundleName + formInfo.moduleName);
1192      if (appName != null) {
1193        formInfo.appName = appName;
1194      }
1195      AppStorage.setOrCreate('formAppInfo', formInfo);
1196      if (!this.isPad) {
1197        this.showFormManager(formInfo);
1198      } else {
1199        formDialog.open();
1200      }
1201    };
1202    menuInfoList.push(addFormToDeskTopMenu);
1203
1204    let formCenterMenu: MenuInfo = new MenuInfo();
1205    formCenterMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
1206    formCenterMenu.menuImgSrc = '/common/pics/ic_form_center.svg';
1207    formCenterMenu.menuText = $r('app.string.form_center');
1208    formCenterMenu.onMenuClick = (): void => {
1209      Log.showInfo(TAG, 'Launcher click menu into form center view.');
1210      if (!this.isPad) {
1211        windowManager.createWindowWithName(windowManager.FORM_SERVICE_WINDOW_NAME, windowManager.RECENT_RANK);
1212      }
1213    };
1214    menuInfoList.push(formCenterMenu);
1215
1216    const deleteFormFromDeskTop = new MenuInfo();
1217    deleteFormFromDeskTop.menuType = CommonConstants.MENU_TYPE_FIXED;
1218    deleteFormFromDeskTop.menuImgSrc = '/common/pics/ic_public_remove.svg';
1219    deleteFormFromDeskTop.menuText = $r('app.string.delete_form');
1220    deleteFormFromDeskTop.onMenuClick = () => {
1221      Log.showDebug(TAG, 'Launcher click menu item remove form to desktop view');
1222      const formAnimateData: {
1223        cardId: number,
1224        isOpenRemoveFormDialog: boolean,
1225      } = { cardId: formInfo.cardId, isOpenRemoveFormDialog: true };
1226      AppStorage.setOrCreate('formAnimateData', formAnimateData);
1227      dialog.open();
1228    };
1229    menuInfoList.push(deleteFormFromDeskTop);
1230    return menuInfoList;
1231  }
1232
1233  buildRenameMenuInfoList(folderItemInfo, menuCallback): MenuInfo[] {
1234    const menuInfoList = new Array<MenuInfo>();
1235    const renameMenu = new MenuInfo();
1236    renameMenu.menuType = CommonConstants.MENU_TYPE_DYNAMIC;
1237    renameMenu.menuImgSrc = StyleConstants.DEFAULT_RENAME_IMAGE;
1238    renameMenu.menuText = $r('app.string.rename_folder');
1239    renameMenu.onMenuClick = () => {
1240      Log.showDebug(TAG, 'Launcher click menu to rename');
1241      menuCallback();
1242    };
1243    menuInfoList.push(renameMenu);
1244    return menuInfoList;
1245  }
1246
1247  /**
1248   * Get PageDesktopStyleConfig.
1249   */
1250  getPageDesktopStyleConfig() {
1251    return this.pageDesktopStyleConfig;
1252  }
1253
1254  /**
1255   * Get workSpaceWidth.
1256   */
1257  getWorkSpaceWidth() {
1258    return AppStorage.get('workSpaceWidth');
1259  }
1260
1261  /**
1262   * Get workSpaceHeight.
1263   */
1264  getWorkSpaceHeight() {
1265    return AppStorage.get('workSpaceHeight');
1266  }
1267
1268  /**
1269   * Get getAppPageStartConfig.
1270   */
1271  getAppPageStartConfig() {
1272    return this.mSettingsModel.getAppPageStartConfig();
1273  }
1274
1275  /**
1276   * click event
1277   *
1278   * @param abilityName ability name
1279   * @param bundleName bundle name
1280   */
1281  onAppClick(abilityName: string, bundleName: string, moduleName: string) {
1282    if (!this.isPad) {
1283      this.jumpTo(abilityName, bundleName, moduleName);
1284      return;
1285    }
1286    Log.showDebug(TAG, `onAppClick keyName ${bundleName + abilityName + moduleName}`);
1287    AppStorage.setOrCreate('selectDesktopAppItem', bundleName + abilityName + moduleName);
1288  }
1289
1290  /**
1291   * double click event
1292   *
1293   * @param abilityName ability name
1294   * @param bundleName bundle name
1295   */
1296  onAppDoubleClick(abilityName: string, bundleName: string, moduleName: string): void {
1297    AppStorage.setOrCreate('selectDesktopAppItem', '');
1298    this.jumpTo(abilityName, bundleName, moduleName);
1299  }
1300
1301  /**
1302   * other app publish card to pageDesktop
1303   *
1304   * @param parameters
1305   */
1306  async publishCardToDesktop(parameters:any) {
1307    Log.showDebug(TAG, 'publishCardToDesktop');
1308    const formItem = await FormManager.getInstance().getFormCardItemByWant(parameters);
1309    localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_FORM_ITEM_ADD, formItem);
1310  }
1311
1312  /**
1313   * add card to pageDesktop
1314   *
1315   * @param appInfo
1316   */
1317  async createCardToDeskTop(formCardItem) {
1318    Log.showDebug(TAG, `createCardToDeskTop formCardItem id: ${formCardItem.cardId}`);
1319    const cardItemInfo = this.createNewCardItemInfo(formCardItem);
1320
1321    let formInfoList: any = this.mFormListInfoCacheManager.getCache(KEY_FORM_LIST);
1322    if (formInfoList == CommonConstants.INVALID_VALUE) {
1323      formInfoList = new Array<CardItemInfo>();
1324    }
1325    formInfoList.push(cardItemInfo);
1326    this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, formInfoList);
1327
1328    const result = await this.mFormModel.updateFormInfoById(cardItemInfo);
1329    if (result) {
1330      const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
1331      const cardItemLayoutInfo = {
1332        cardId: cardItemInfo.cardId,
1333        typeId: CommonConstants.TYPE_CARD,
1334        area: FormManager.getInstance().getCardSize(cardItemInfo.cardDimension),
1335        page: 0,
1336        row: 0,
1337        column: 0
1338      };
1339
1340      const needNewPage: boolean =this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfo, cardItemLayoutInfo);
1341      const curPageIndex = this.mPageDesktopModel.getPageIndex();
1342      if (needNewPage) {
1343        gridLayoutInfo.layoutDescription.pageCount = gridLayoutInfo.layoutDescription.pageCount + 1;
1344        for (let index = 0; index < gridLayoutInfo.layoutInfo.length; index++) {
1345          if (gridLayoutInfo.layoutInfo[index].page > curPageIndex) {
1346            gridLayoutInfo.layoutInfo[index].page++;
1347          }
1348        }
1349      }
1350
1351      // Push card into the layoutInfo
1352      gridLayoutInfo.layoutInfo.push(cardItemLayoutInfo as LauncherDragItemInfo);
1353      this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
1354      if (needNewPage) {
1355        this.mPageDesktopModel.setPageIndex(curPageIndex + 1);
1356      }
1357    }
1358    this.getGridList();
1359  }
1360
1361  /**
1362   * create new cardItemInfo by formItemInfo
1363   *
1364   * @param formCardItem
1365   */
1366  private createNewCardItemInfo(formCardItem): CardItemInfo {
1367    const cardItemInfo = new CardItemInfo();
1368    cardItemInfo.cardId = formCardItem.cardId;
1369    cardItemInfo.cardName = formCardItem.cardName;
1370    cardItemInfo.bundleName = formCardItem.bundleName;
1371    cardItemInfo.abilityName = formCardItem.abilityName;
1372    cardItemInfo.moduleName = formCardItem.moduleName;
1373    cardItemInfo.formConfigAbility = formCardItem.formConfigAbility;
1374    cardItemInfo.appLabelId = formCardItem.appLabelId;
1375    cardItemInfo.cardDimension = formCardItem.cardDimension;
1376    return cardItemInfo;
1377  }
1378
1379  private ifStringIsNull(str): boolean {
1380    if (str == undefined || str == '' || str == null) {
1381      return true;
1382    }
1383    return false;
1384  }
1385
1386  private addNewInstalledInfo(totalAppInfoList, pageDesktopInfo): void {
1387    for (const i in totalAppInfoList) {
1388      let hasInstalled = false;
1389      for (const j in pageDesktopInfo) {
1390        if (totalAppInfoList[i].keyName == pageDesktopInfo[j].keyName) {
1391          hasInstalled = true;
1392          break;
1393        }
1394      }
1395      if (!hasInstalled) {
1396        pageDesktopInfo.push(totalAppInfoList[i]);
1397      }
1398    }
1399  }
1400
1401  private removeBottomBarInfo(pageDesktopInfo) {
1402    let bottomAppList = [];
1403    bottomAppList = AppStorage.get('residentList');
1404    Log.showDebug(TAG, `removeBottomBarInfo bottomAppList length: ${bottomAppList.length}`);
1405    if (!CheckEmptyUtils.isEmptyArr(bottomAppList)) {
1406      for (let i = 0; i < bottomAppList.length; i++) {
1407        Log.showDebug(TAG, `removeBottomBarInfo bottomAppList[${i}]: ${JSON.stringify(bottomAppList[i])}`);
1408        const appInfo = pageDesktopInfo.find(item => {
1409          if (item.keyName == bottomAppList[i].keyName) {
1410            return true;
1411          }
1412        });
1413        if (!this.ifInfoIsNull(appInfo)) {
1414          const index = pageDesktopInfo.indexOf(appInfo);
1415          pageDesktopInfo.splice(index, 1);
1416        }
1417      }
1418    }
1419  }
1420
1421  private removeFolderInfo(pageDesktopInfo): void {
1422    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
1423    const layoutInfo = gridLayoutInfo.layoutInfo;
1424    for (let i = 0; i < layoutInfo.length; i++) {
1425      if (layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
1426        for (let j = 0; j < layoutInfo[i].layoutInfo.length; j++) {
1427          for (let k = 0; k < layoutInfo[i].layoutInfo[j].length; k++) {
1428            const appInfo = pageDesktopInfo.find(item => {
1429              if (item.keyName == layoutInfo[i].layoutInfo[j][k].keyName) {
1430                return true;
1431              }
1432            });
1433            if (!this.ifInfoIsNull(appInfo)) {
1434              const index = pageDesktopInfo.indexOf(appInfo);
1435              pageDesktopInfo.splice(index, 1);
1436              Log.showDebug(TAG, `removeFolderInfo keyName: ${appInfo.keyName}`);
1437            }
1438          }
1439        }
1440      }
1441    }
1442  }
1443
1444  /**
1445   * set start app info
1446   */
1447  private setStartAppInfo() {
1448    AppStorage.setOrCreate('startAppIconInfo', {
1449      appIconSize: 0,
1450      appIconHeight: 0,
1451      appIconPositionX: 0,
1452      appIconPositionY: 0
1453    });
1454  }
1455}