From e9f39e470d58cf029f4b4c3ea067cebc304df158 Mon Sep 17 00:00:00 2001 From: Jinkun Jang Date: Wed, 13 Mar 2013 01:38:55 +0900 Subject: [PATCH] Tizen 2.1 base --- CMakeLists.txt | 32 + LICENSE.Flora | 206 ++++ NOTICE | 3 + inc/HmApplicationUtils.h | 93 ++ inc/HmCustomIconListProvider.h | 133 ++ inc/HmCustomPageControl.h | 184 +++ inc/HmCustomPageMarker.h | 121 ++ inc/HmGenericDatabaseManager.h | 169 +++ inc/HmHomeApp.h | 79 ++ inc/HmHomeForm.h | 162 +++ inc/HmHomeItemInfo.h | 163 +++ inc/HmHomePresentationModel.h | 236 ++++ inc/HmICustomPageControlEventListener.h | 69 ++ inc/HmICustomPageMarkerEventListener.h | 47 + inc/HmIHomePresentationModelListener.h | 69 ++ inc/HmIPackageInfoListListener.h | 53 + inc/HmIPageControlItemProvider.h | 76 ++ inc/HmMainFrame.h | 52 + inc/HmPackageInfoListRetrieveThread.h | 73 ++ inc/HmProgressPanel.h | 80 ++ inc/HmTypes.h | 118 ++ manifest.xml | 34 + packaging/apps.Home.spec | 62 + res/ara-AE.xml | 14 + res/aze-AZ.xml | 14 + res/bul-BG.xml | 14 + res/cat-ES.xml | 14 + res/ces-CZ.xml | 14 + res/dan-DK.xml | 14 + res/deu-DE.xml | 14 + res/ell-GR.xml | 14 + res/eng-GB.xml | 14 + res/eng-PH.xml | 14 + res/eng-US.xml | 14 + res/est-EE.xml | 14 + res/eus-ES.xml | 14 + res/fin-FI.xml | 14 + res/fra-CA.xml | 14 + res/fra-FR.xml | 14 + res/gle-IE.xml | 14 + res/glg-ES.xml | 14 + res/hin-IN.xml | 14 + res/hrv-HR.xml | 14 + res/hun-HU.xml | 14 + res/hye-AM.xml | 14 + res/isl-IS.xml | 14 + res/ita-IT.xml | 14 + res/jpn-JP.xml | 14 + res/kat-GE.xml | 14 + res/kaz-KZ.xml | 14 + res/kor-KR.xml | 14 + res/lav-LV.xml | 14 + res/lit-LT.xml | 14 + res/mkd-MK.xml | 14 + res/nld-NL.xml | 14 + res/nob-NO.xml | 14 + res/pol-PL.xml | 14 + res/por-BR.xml | 14 + res/por-PT.xml | 14 + res/ron-RO.xml | 14 + res/rus-RU.xml | 14 + res/screen-density-xhigh/BG.png | Bin 0 -> 101297 bytes res/screen-density-xhigh/Menu_Btn_Uninstall.png | Bin 0 -> 6124 bytes .../Menu_Btn_Uninstall_press.png | Bin 0 -> 6302 bytes res/screen-density-xhigh/Menu_Btn_setting.png | Bin 0 -> 4380 bytes .../Menu_Btn_setting_press.png | Bin 0 -> 3331 bytes res/screen-density-xhigh/Page_indicator_001.png | Bin 0 -> 3046 bytes res/screen-density-xhigh/Page_indicator_002.png | Bin 0 -> 3540 bytes res/screen-density-xhigh/Page_indicator_01.png | Bin 0 -> 3890 bytes res/screen-density-xhigh/Page_indicator_010.png | Bin 0 -> 4125 bytes res/screen-density-xhigh/Page_indicator_02.png | Bin 0 -> 4093 bytes res/screen-density-xhigh/Page_indicator_03.png | Bin 0 -> 4129 bytes res/screen-density-xhigh/Page_indicator_04.png | Bin 0 -> 4006 bytes res/screen-density-xhigh/Page_indicator_05.png | Bin 0 -> 4123 bytes res/screen-density-xhigh/Page_indicator_06.png | Bin 0 -> 4145 bytes res/screen-density-xhigh/Page_indicator_07.png | Bin 0 -> 3994 bytes res/screen-density-xhigh/Page_indicator_08.png | Bin 0 -> 4141 bytes res/screen-density-xhigh/Page_indicator_09.png | Bin 0 -> 4141 bytes res/screen-density-xhigh/default_app_icon.png | Bin 0 -> 13745 bytes res/screen-density-xhigh/progressing00.png | Bin 0 -> 3301 bytes res/screen-density-xhigh/progressing00_big.png | Bin 0 -> 6091 bytes res/screen-density-xhigh/progressing01.png | Bin 0 -> 3526 bytes res/screen-density-xhigh/progressing01_big.png | Bin 0 -> 6551 bytes res/screen-density-xhigh/progressing02.png | Bin 0 -> 3270 bytes res/screen-density-xhigh/progressing02_big.png | Bin 0 -> 5982 bytes res/screen-density-xhigh/progressing03.png | Bin 0 -> 3485 bytes res/screen-density-xhigh/progressing03_big.png | Bin 0 -> 6439 bytes res/screen-density-xhigh/progressing04.png | Bin 0 -> 3249 bytes res/screen-density-xhigh/progressing04_big.png | Bin 0 -> 6005 bytes res/screen-density-xhigh/progressing05.png | Bin 0 -> 3479 bytes res/screen-density-xhigh/progressing05_big.png | Bin 0 -> 6520 bytes res/screen-density-xhigh/progressing06.png | Bin 0 -> 3289 bytes res/screen-density-xhigh/progressing06_big.png | Bin 0 -> 5931 bytes res/screen-density-xhigh/progressing07.png | Bin 0 -> 3474 bytes res/screen-density-xhigh/progressing07_big.png | Bin 0 -> 6537 bytes res/screen-size-normal/IDL_FORM.xml | 34 + res/slk-SK.xml | 14 + res/slv-SI.xml | 14 + res/spa-ES.xml | 14 + res/spa-MX.xml | 14 + res/srp-RS.xml | 14 + res/swe-SE.xml | 14 + res/tur-TR.xml | 14 + res/ukr-UA.xml | 14 + res/uzb-UZ.xml | 14 + res/zho-CN.xml | 14 + res/zho-HK.xml | 14 + res/zho-SG.xml | 14 + res/zho-TW.xml | 14 + shared/data/nofile.dummy | 0 shared/res/screen-density-xhigh/mainmenu.png | Bin 0 -> 13745 bytes shared/trusted/nofile.dummy | 0 src/HmApplicationUtils.cpp | 315 +++++ src/HmCustomIconListProvider.cpp | 228 ++++ src/HmCustomPageControl.cpp | 947 ++++++++++++++ src/HmCustomPageMarker.cpp | 314 +++++ src/HmGenericDatabaseManager.cpp | 679 ++++++++++ src/HmHomeApp.cpp | 219 ++++ src/HmHomeEntry.cpp | 70 ++ src/HmHomeForm.cpp | 659 ++++++++++ src/HmHomeItemInfo.cpp | 187 +++ src/HmHomePresentationModel.cpp | 1295 ++++++++++++++++++++ src/HmMainFrame.cpp | 48 + src/HmPackageInfoListRetrieveThread.cpp | 241 ++++ src/HmProgressPanel.cpp | 215 ++++ src/HmTypes.cpp | 104 ++ 126 files changed, 8583 insertions(+) create mode 100644 CMakeLists.txt create mode 100755 LICENSE.Flora create mode 100755 NOTICE create mode 100644 inc/HmApplicationUtils.h create mode 100644 inc/HmCustomIconListProvider.h create mode 100644 inc/HmCustomPageControl.h create mode 100644 inc/HmCustomPageMarker.h create mode 100644 inc/HmGenericDatabaseManager.h create mode 100644 inc/HmHomeApp.h create mode 100644 inc/HmHomeForm.h create mode 100644 inc/HmHomeItemInfo.h create mode 100644 inc/HmHomePresentationModel.h create mode 100644 inc/HmICustomPageControlEventListener.h create mode 100644 inc/HmICustomPageMarkerEventListener.h create mode 100644 inc/HmIHomePresentationModelListener.h create mode 100644 inc/HmIPackageInfoListListener.h create mode 100644 inc/HmIPageControlItemProvider.h create mode 100644 inc/HmMainFrame.h create mode 100644 inc/HmPackageInfoListRetrieveThread.h create mode 100644 inc/HmProgressPanel.h create mode 100644 inc/HmTypes.h create mode 100644 manifest.xml create mode 100755 packaging/apps.Home.spec create mode 100644 res/ara-AE.xml create mode 100644 res/aze-AZ.xml create mode 100644 res/bul-BG.xml create mode 100644 res/cat-ES.xml create mode 100644 res/ces-CZ.xml create mode 100644 res/dan-DK.xml create mode 100644 res/deu-DE.xml create mode 100644 res/ell-GR.xml create mode 100644 res/eng-GB.xml create mode 100644 res/eng-PH.xml create mode 100644 res/eng-US.xml create mode 100644 res/est-EE.xml create mode 100644 res/eus-ES.xml create mode 100644 res/fin-FI.xml create mode 100644 res/fra-CA.xml create mode 100644 res/fra-FR.xml create mode 100644 res/gle-IE.xml create mode 100644 res/glg-ES.xml create mode 100644 res/hin-IN.xml create mode 100644 res/hrv-HR.xml create mode 100644 res/hun-HU.xml create mode 100644 res/hye-AM.xml create mode 100644 res/isl-IS.xml create mode 100644 res/ita-IT.xml create mode 100644 res/jpn-JP.xml create mode 100644 res/kat-GE.xml create mode 100644 res/kaz-KZ.xml create mode 100644 res/kor-KR.xml create mode 100644 res/lav-LV.xml create mode 100644 res/lit-LT.xml create mode 100644 res/mkd-MK.xml create mode 100644 res/nld-NL.xml create mode 100644 res/nob-NO.xml create mode 100644 res/pol-PL.xml create mode 100644 res/por-BR.xml create mode 100644 res/por-PT.xml create mode 100644 res/ron-RO.xml create mode 100644 res/rus-RU.xml create mode 100644 res/screen-density-xhigh/BG.png create mode 100644 res/screen-density-xhigh/Menu_Btn_Uninstall.png create mode 100644 res/screen-density-xhigh/Menu_Btn_Uninstall_press.png create mode 100644 res/screen-density-xhigh/Menu_Btn_setting.png create mode 100644 res/screen-density-xhigh/Menu_Btn_setting_press.png create mode 100644 res/screen-density-xhigh/Page_indicator_001.png create mode 100644 res/screen-density-xhigh/Page_indicator_002.png create mode 100644 res/screen-density-xhigh/Page_indicator_01.png create mode 100644 res/screen-density-xhigh/Page_indicator_010.png create mode 100644 res/screen-density-xhigh/Page_indicator_02.png create mode 100644 res/screen-density-xhigh/Page_indicator_03.png create mode 100644 res/screen-density-xhigh/Page_indicator_04.png create mode 100644 res/screen-density-xhigh/Page_indicator_05.png create mode 100644 res/screen-density-xhigh/Page_indicator_06.png create mode 100644 res/screen-density-xhigh/Page_indicator_07.png create mode 100644 res/screen-density-xhigh/Page_indicator_08.png create mode 100644 res/screen-density-xhigh/Page_indicator_09.png create mode 100644 res/screen-density-xhigh/default_app_icon.png create mode 100644 res/screen-density-xhigh/progressing00.png create mode 100644 res/screen-density-xhigh/progressing00_big.png create mode 100644 res/screen-density-xhigh/progressing01.png create mode 100644 res/screen-density-xhigh/progressing01_big.png create mode 100644 res/screen-density-xhigh/progressing02.png create mode 100644 res/screen-density-xhigh/progressing02_big.png create mode 100644 res/screen-density-xhigh/progressing03.png create mode 100644 res/screen-density-xhigh/progressing03_big.png create mode 100644 res/screen-density-xhigh/progressing04.png create mode 100644 res/screen-density-xhigh/progressing04_big.png create mode 100644 res/screen-density-xhigh/progressing05.png create mode 100644 res/screen-density-xhigh/progressing05_big.png create mode 100644 res/screen-density-xhigh/progressing06.png create mode 100644 res/screen-density-xhigh/progressing06_big.png create mode 100644 res/screen-density-xhigh/progressing07.png create mode 100644 res/screen-density-xhigh/progressing07_big.png create mode 100644 res/screen-size-normal/IDL_FORM.xml create mode 100644 res/slk-SK.xml create mode 100644 res/slv-SI.xml create mode 100644 res/spa-ES.xml create mode 100644 res/spa-MX.xml create mode 100644 res/srp-RS.xml create mode 100644 res/swe-SE.xml create mode 100644 res/tur-TR.xml create mode 100644 res/ukr-UA.xml create mode 100644 res/uzb-UZ.xml create mode 100644 res/zho-CN.xml create mode 100644 res/zho-HK.xml create mode 100644 res/zho-SG.xml create mode 100644 res/zho-TW.xml create mode 100644 shared/data/nofile.dummy create mode 100644 shared/res/screen-density-xhigh/mainmenu.png create mode 100644 shared/trusted/nofile.dummy create mode 100644 src/HmApplicationUtils.cpp create mode 100644 src/HmCustomIconListProvider.cpp create mode 100644 src/HmCustomPageControl.cpp create mode 100644 src/HmCustomPageMarker.cpp create mode 100644 src/HmGenericDatabaseManager.cpp create mode 100644 src/HmHomeApp.cpp create mode 100644 src/HmHomeEntry.cpp create mode 100644 src/HmHomeForm.cpp create mode 100644 src/HmHomeItemInfo.cpp create mode 100644 src/HmHomePresentationModel.cpp create mode 100644 src/HmMainFrame.cpp create mode 100644 src/HmPackageInfoListRetrieveThread.cpp create mode 100644 src/HmProgressPanel.cpp create mode 100644 src/HmTypes.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d64264f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,32 @@ +# Target name and PKGID +## TODO : set application name and ID +SET(this_target Home) +SET(PKGID cwkuromqdr) + +# include directory +INCLUDE_DIRECTORIES( + /usr/include/osp + inc + ) + +# Source files +FILE(GLOB ${this_target}_SOURCE_FILES src/*.cpp) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE -DCUSTOM_TEXT_RENDERING") + +# Create executable +SET(CMAKE_EXECUTABLE_SUFFIX ".exe") +ADD_EXECUTABLE (${this_target} ${${this_target}_SOURCE_FILES}) + +# Set link libraries and link options +## TODO : add more link libraries and options +TARGET_LINK_LIBRARIES(${this_target} -L/usr/lib/osp osp-appfw osp-uifw osp-media osp-image pthread) +TARGET_LINK_LIBRARIES(${this_target} -Xlinker --allow-shlib-undefined -pthread -pie) + +# Copy info, data, res, and icons directories +INSTALL(TARGETS ${this_target} DESTINATION ../usr/apps/${PKGID}/bin) + +# Copy resource +INSTALL(FILES ${CMAKE_SOURCE_DIR}/manifest.xml DESTINATION ../usr/apps/${PKGID}/info) +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ../usr/apps/${PKGID}) +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/shared DESTINATION ../usr/apps/${PKGID}) diff --git a/LICENSE.Flora b/LICENSE.Flora new file mode 100755 index 0000000..9c95663 --- /dev/null +++ b/LICENSE.Flora @@ -0,0 +1,206 @@ +Flora License + +Version 1.0, May, 2012 + +http://floralicense.org/license/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and +all other entities that control, are controlled by, or are +under common control with that entity. For the purposes of +this definition, "control" means (i) the power, direct or indirect, +to cause the direction or management of such entity, +whether by contract or otherwise, or (ii) ownership of fifty percent (50%) +or more of the outstanding shares, or (iii) beneficial ownership of +such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice +that is included in or attached to the work (an example is provided +in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, +as a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, +or merely link (or bind by name) to the interfaces of, the Work and +Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor +for inclusion in the Work by the copyright owner or by an individual or +Legal Entity authorized to submit on behalf of the copyright owner. +For the purposes of this definition, "submitted" means any form of +electronic, verbal, or written communication sent to the Licensor or +its representatives, including but not limited to communication on +electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding +communication that is conspicuously marked or otherwise designated +in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Compatibility Definition Document +and passes the Compatibility Test Suite as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work +solely as incorporated into a Tizen Certified Platform, where such +license applies only to those patent claims licensable by such +Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work solely +as incorporated into a Tizen Certified Platform to which such +Contribution(s) was submitted. If You institute patent litigation +against any entity (including a cross-claim or counterclaim +in a lawsuit) alleging that the Work or a Contribution incorporated +within the Work constitutes direct or contributory patent infringement, +then any patent licenses granted to You under this License for that +Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. You must retain, in the Source form of any Derivative Works that + You distribute, all copyright, patent, trademark, and attribution + notices from the Source form of the Work, excluding those notices + that do not pertain to any part of the Derivative Works; and + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable + copy of the attribution notices contained within such NOTICE file, + excluding those notices that do not pertain to any part of + the Derivative Works, in at least one of the following places: + within a NOTICE text file distributed as part of the Derivative Works; + within the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the Derivative Works, + if and wherever such third-party notices normally appear. + The contents of the NOTICE file are for informational purposes only + and do not modify the License. + +You may add Your own attribution notices within Derivative Works +that You distribute, alongside or as an addendum to the NOTICE text +from the Work, provided that such additional attribution notices +cannot be construed as modifying the License. You may add Your own +copyright statement to Your modifications and may provide additional or +different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works +as a whole, provided Your use, reproduction, and distribution of +the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Flora License to your work + +To apply the Flora License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Flora License, Version 1.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/NOTICE b/NOTICE new file mode 100755 index 0000000..9ec42be --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Flora License, Version 1. +Please, see the LICENSE.Flora file for Flora License, Version 1 terms and conditions. \ No newline at end of file diff --git a/inc/HmApplicationUtils.h b/inc/HmApplicationUtils.h new file mode 100644 index 0000000..677bc57 --- /dev/null +++ b/inc/HmApplicationUtils.h @@ -0,0 +1,93 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmApplicationUtils.h + * @brief Keeps the declaration for Utility functions, + * declaration of the various Utility function which may be used throughout the application + */ + +#ifndef _HM_APPLICATION_UTILS_H_ +#define _HM_APPLICATION_UTILS_H_ + +#include + +/** + * @class ApplicationUtils + * @brief Keeps the static methods used throughout the application + */ +class ApplicationUtils +{ +public: + /** + * Creates an icon's bitmap to be placed in main menu + * + * @return Bitmap*, new bitmap for the application icon. + * @param[in] imagePath, the absolute path of the image file. + * @param[in] appCaption, Caption of the application. + */ + static Tizen::Graphics::Bitmap* GetApplicationIconBitmapN(const Tizen::Base::String& imagePath, const Tizen::Base::String& appCaption = L"", bool isResourceBitmap = false); + + /** + * Decodes a bitmap. + * + * @return Tizen::Graphics::Bitmap*, the decoded images. + * @param[in] Image's absolute path. + */ + static Tizen::Graphics::Bitmap* GetBitmapN(const Tizen::Base::String& imageAbsolutePath); + + /** + * Decodes a bitmap which is present in the resource. + * + * @return Tizen::Graphics::Bitmap*, the decoded images. + * @param[in] name of the resource image + */ + static Tizen::Graphics::Bitmap* GetResourceBitmapN(const Tizen::Base::String& imageName); + + /** + * fetches the string from the localized string resource. + * + * @return E_SUCCESS, for successful execution else system wide error code + * @param[in] stringId, the id of the string + * @param[out] retString, retrieved string value for the mentioned string id. + */ + static result GetStringResource(const Tizen::Base::String& stringId, Tizen::Base::String& retString); + + /** + * Shows delete confirmation message + * + * @return int, the ID of the command pressed + * @param[in] name, name of the application to be deleted + * + */ + static int ShowDeletePopup(Tizen::Base::String& applicationName); + +private: + /** + * Constructor + * Intentionally declared it in private scope as all the methods in this class are static, so creating object is not required + */ + ApplicationUtils(void); + + /** + * Destructor + * Intentionally declared it in private scope as all the methods in this class are static, so creating/destroying object is not required + */ + virtual ~ApplicationUtils(void); + +}; + +#endif //_HM_APPLICATION_UTILS_H_ diff --git a/inc/HmCustomIconListProvider.h b/inc/HmCustomIconListProvider.h new file mode 100644 index 0000000..2743704 --- /dev/null +++ b/inc/HmCustomIconListProvider.h @@ -0,0 +1,133 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmCustomIconListProvider.h + * @brief This is the class declaration for the IconListItemProviderCustom class + * This class contains the functions which are required managing the IconListView's items + */ + +#ifndef _HM_CUSTOM_ICON_LIST_ITEM_PROVIDER_H_ +#define _HM_CUSTOM_ICON_LIST_ITEM_PROVIDER_H_ + +#include +#include +#include "HmIPageControlItemProvider.h" + +/** + * @class CustomIconListProvider + * @brief Provider implementation for the HmCustomIconListViews in pagging control + */ +class CustomIconListProvider + : public Tizen::Base::Object + , public Tizen::Ui::Controls::IIconListViewItemProvider +{ +public: + /** + * Constructor + */ + CustomIconListProvider(int index); + + /** + * Destructor + */ + ~CustomIconListProvider(void); + + /** + * Gets the value of edit mode + */ + bool GetEditMode(void) const; + + /** + * Returns the item, which is getting moved currently + */ + Tizen::Ui::Controls::IconListViewItem* GetMovingItem(void) const; + + /** + * Returns the Moving Item's index + */ + int GetMovingItemIndex() const; + + /** + * Returns the item provider instance. + */ + IPageControlItemProvider* GetPageControlItemProvider(void); + + /** + * Sets the value of edit mode + */ + void SetEditMode(bool editMode); + + /** + * Sets the index of this provider object. + */ + void SetIndex(int index); + + /** + * Sets the maximum number of icons in a page. + */ + void SetMaxCountOfIcons(int iconCount); + + /** + * Sets the Moving items instance + */ + void SetMovingItem(Tizen::Ui::Controls::IconListViewItem* pMovedItem); + + /** + * Set the index of moving item, for projecting the expected project. + */ + void SetMovingItemIndex(int movedIndex); + + /** + * Sets the item Provider for this panel. + */ + void SetPageControlItemProvider(IPageControlItemProvider* pItemProvider); + + /** + * Sets the moving item to be egnored while drawing, as this is an invalid item now + */ + void SetProjectedItemInvalid(bool isInvalid); + + // from IIconListViewItemProvider + virtual Tizen::Ui::Controls::IconListViewItem* CreateItem(int index); + virtual bool DeleteItem(int index, Tizen::Ui::Controls::IconListViewItem* pItem); + virtual int GetItemCount(void); + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + CustomIconListProvider(const CustomIconListProvider&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + CustomIconListProvider& operator =(const CustomIconListProvider&); + +private: + bool __editMode; // keeps the value of editmode + bool __isProjectedItemInvalid; // Is the projection item to be egnored + int __index; // keeps track of index + int __iconsPerPage; // number of icons per page + int __currentIndex; // the index of current projected item + IPageControlItemProvider* __pPageItemProvider; // item provider instance + Tizen::Ui::Controls::IconListViewItem* __pMovementItem; //The item pointer to be projected in expected position + Tizen::Graphics::Bitmap* __pOverayBitmap; //The close button bitmap + + +}; + +#endif //_HM_CUSTOM_ICON_LIST_ITEM_PROVIDER_H_ diff --git a/inc/HmCustomPageControl.h b/inc/HmCustomPageControl.h new file mode 100644 index 0000000..94b7a3b --- /dev/null +++ b/inc/HmCustomPageControl.h @@ -0,0 +1,184 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmCustomPageControl.h + * @brief Keeps declaration of the HmCustomPageControl + * declares HmCustomPageControl class, it overrides default scrolling functionality of IconListView + */ + +#ifndef _HM_CUSTOM_PAGE_CONTROL_H_ +#define _HM_CUSTOM_PAGE_CONTROL_H_ + +#include +#include + +class HomeItemInfo; +class ICustomPageControlEventListener; +class IPageControlItemProvider; + +/** + * @class CustomPageControl + * @brief This is the control which handles page by page scrolling of the application icons. + * It contains a custom IconListView and Provider for it. + */ +class CustomPageControl + : public Tizen::Ui::Controls::Panel + , public Tizen::Ui::Controls::IIconListViewItemEventListener + , public Tizen::Base::Runtime::ITimerEventListener + , public Tizen::Ui::ITouchEventListener + , public Tizen::Ui::ITouchLongPressGestureEventListener +{ +public: + /** + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor. + */ + CustomPageControl(void); + + /** + * Destructor, this destructor overrides ~Tizen::Ui::Controls::Panel + */ + virtual ~CustomPageControl(void); + + /** + * This function constructs the control properly + */ + result Construct(const Tizen::Graphics::Rectangle& controlRect, int noOfPages, int pageWidth); + + /** + * Adds a new page in the page control + */ + result AddPage(void); + + /** + * Returns currently selected page number + */ + int GetCurrentSelectedPage(void); + + /** + * Returns currently selected page number + */ + Tizen::Base::Collection::ArrayList* GetIconLists(void); + + /** + * returns the total no. of pages in the control + */ + const int GetPageCount(void); + + /** + * Marks a page to be deleted + */ + void MarkPageToDelete(int pageNumber); + + /** + * Scrolls to the next or previous page on crossing the bounds while moving icons in edit mode + */ + void MovePage(void); + + /** + * Sets the maximum number of icons in one page + */ + void SetMaxNumberOfIcons(int iconsCount); + + /** + * Sets the listener to intercept events on the page control. + */ + void SetPageControlEventListener(ICustomPageControlEventListener* pListener); + + /** + * Sets item provider for the Page control + */ + void SetPageControlItemProvider(IPageControlItemProvider* pItemProvider); + + /** + * Scrolls to the specified page number + */ + void SetPageSelected(int pageNumber); + + /** + * Enables/Disables edit mode + */ + void ToggleEditMode(void); + + // from IIconListViewItemEventListener + virtual void OnIconListViewItemStateChanged(Tizen::Ui::Controls::IconListView& iconListView, int index, Tizen::Ui::Controls::IconListViewItemStatus status); + virtual void OnIconListViewOverlayBitmapSelected(Tizen::Ui::Controls::IconListView& iconListView, int index, int overlayBitmapId); + + // From ITimerEventListener + virtual void OnTimerExpired(Tizen::Base::Runtime::Timer& timer); + + //from ITouchEventListener + virtual void OnTouchCanceled(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchFocusIn(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchFocusOut(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchMoved(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + virtual void OnTouchPressed(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + virtual void OnTouchReleased(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + + // From ITouchLongPressGestureEventListener + virtual void OnLongPressGestureCanceled(Tizen::Ui::TouchLongPressGestureDetector& gestureDetector) {} + virtual void OnLongPressGestureDetected(Tizen::Ui::TouchLongPressGestureDetector& gestureDetector); + +private: + /** + * Removes a page from the Page control + */ + result RemovePage(int pageNumber); + + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + CustomPageControl(const CustomPageControl&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + CustomPageControl& operator =(const CustomPageControl&); + +private: + bool __hasPageMoved; // keeps info if the page transition completed or not + bool __isDragging; // tell if an icon is being dragged + bool __isInEditMode; // tells if the control is in edit mode or not + bool __needAnimation; //indicates, if scroll animation needs to be played. + HomeItemInfo* __pDraggingAppInfo; // the app info of moving item + ICustomPageControlEventListener* __pEventListener; // the listener object to notify about the events + int __currentIndex; //the index in which the moving item is projected at the moment + int __currentPageNumber; //Currently shown page number + int __iconsCount; //max number of icons per page + int __pageNumber; // current page number + int __pageToBeDeleted; // page number to be deleted + int __pageWidth; // width of one page + int __startIndex; // start index of the dragged icon + int __sweepTraveled; // the distance the touch has traveled, + int __totalPages; // total number of pages in this control + IPageControlItemProvider* __pPageItemProvider; // the provider for the PageItem + Tizen::Base::Collection::ArrayList* __pIconListProviders; // list of provider objects + Tizen::Base::Collection::ArrayList* __pIconLists; //keeps the list of IconListViews + Tizen::Base::Runtime::Timer* __pPageMovementTimer; // Time to be created for the duration for Page Movement + Tizen::Graphics::Bitmap* __pMovingItemBitmap; //The item bitmap of the moving item + Tizen::Graphics::Point __animationEndPoint; // starting position of touch from where the animation to be started + Tizen::Graphics::Point __animationStartPoint; // starting position control to be animated to. + Tizen::Graphics::Point __dragStartPosition; // starting position of touch dragging an item started + Tizen::Graphics::Point __iconListCurrentPos; // current position of the current page + Tizen::Graphics::Point __iconListRestPosition; // current position of the current page + Tizen::Graphics::Point __touchStartPoint; // starting position of touch from where the scrolling started + Tizen::Ui::Controls::IconListViewItem* __pMovementItem; //The Moving item + Tizen::Ui::Controls::Label* __pMovementLabel; // The label to show current position of touch location, to guide while repositioning + Tizen::Ui::TouchLongPressGestureDetector* __pGetureDetector; //LongTouchGesture detector +}; + +#endif // _HM_CUSTOM_PAGE_CONTROL_H_ diff --git a/inc/HmCustomPageMarker.h b/inc/HmCustomPageMarker.h new file mode 100644 index 0000000..3feac4e --- /dev/null +++ b/inc/HmCustomPageMarker.h @@ -0,0 +1,121 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmCustomPageMarker.h + * @brief Keeps declaration of the CustomPageMarker + * declares CustomPageMarker class, which contains the top bubble's bar which indicates the page number + */ + +#ifndef _HM_CUSTOM_PAGE_MARKER_H_ +#define _HM_CUSTOM_PAGE_MARKER_H_ + +#include +#include "HmICustomPageMarkerEventListener.h" + +/** + * @class CustomPageMarker + * @brief The control which keeps the bubbles and current state of the bubbles + */ +class CustomPageMarker + : public Tizen::Ui::Controls::Panel + , public Tizen::Ui::ITouchEventListener +{ +public: + /** + * Constructor + */ + CustomPageMarker(void); + + /** + * Destructor, this destructor overrides ~Tizen::Ui::Controls::Panel(). + */ + virtual ~CustomPageMarker(void); + + /** + * Constructs the object completely + * + * @param[in] controlRect, position of the control. + * @param[in] noOfPages, total no of bubbles to be initialized with. + * @param[in] markPos, position of the marker within the form. + */ + result Construct(const Tizen::Graphics::Rectangle& controlRect, int bubbleCount = 1); + + /** + * Adds a new bubble in the marker control + * + * @return result, E_SUCCESS if successfully created the control else Error Code. + */ + result AddBubble(void); + + /** + * returns the total no. of bubbles in the control + * + * @return the no of bubbles in the control + */ + const int GetBubbleCount(void); + + /** + * Deletes a bubble from the marker control + * + * @return result, E_SUCCESS if successfully created the control else Error Code. + * @param[in] index, bubble number to be deleted. + */ + result RemoveBubble(int index); + + /** + * Sets the listener to intercept events on the marker control. + * + * @param[in] pListener, Listener object to be notified. + */ + void SetPageMarkerEventListener(ICustomPageMarkerEventListener* pListner); + + /** + * Sets the specified bubble as a current bubble, and highlights it + * + * @return result, E_SUCCESS if successfully created the control else Error Code. + * @param[in] index, bubble number to be highlighted. + */ + void SetSelectedBubble(int index); + + // From ITouchEventListener + virtual void OnTouchPressed(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchReleased(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + virtual void OnTouchMoved(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchFocusIn(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchFocusOut(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchCanceled(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + CustomPageMarker(const CustomPageMarker&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + CustomPageMarker& operator =(const CustomPageMarker&); + +private: + ICustomPageMarkerEventListener* __pMarkerListener; // listener to the marker events + int __bubbleCount; // total number of bubbles in marker control + int __selectedBubble; // currently highlighted bubble in the marker + Tizen::Base::Collection::ArrayList* __pBubbleLabels; // list of labels in the marker control + Tizen::Base::Collection::ArrayList* __pBubbleBitmaps; // the bitmaps to be shown as bubble +}; + +#endif //_HM_CUSTOM_PAGE_MARKER_H_ diff --git a/inc/HmGenericDatabaseManager.h b/inc/HmGenericDatabaseManager.h new file mode 100644 index 0000000..06d3e26 --- /dev/null +++ b/inc/HmGenericDatabaseManager.h @@ -0,0 +1,169 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmGenericDatabaseManager.h + * @brief Keeps the declaration of DatabaseManager and related interfaces + * declaration of the various functions which may be needed for various database operations + */ + +#ifndef _HM_GENERIC_DATABASE_MANAGER_H_ +#define _HM_GENERIC_DATABASE_MANAGER_H_ + +#include +#include + +/** + * @class GenericDatabaseManager + * @brief The class contains declaration of various database functions. + */ +class GenericDatabaseManager + : public Tizen::Base::Object +{ +public: + /** + * Returns an object of the database manager + * + * @return HomeDatabaseManager*, pointer to the singleton object of HomeDatabaseManager + */ + static GenericDatabaseManager* GetInstance(void); + + /** + * Creates or opens(if already created) the database. + * + * @return E_SUCCESS in case of success else system wide error code + * @param[in] dbName, absolute path for the database file. + */ + result CreateDataBase(const Tizen::Base::String& dbName); + + /** + * Creates a Table of given name if not already exists. + * + * @return E_SUCCESS in case of success else system wide error code + * @param[in] tableName, name of the table to be created. + * @param[in] pColumnNames, the names for each columns in the table + * @param[in] pColumnTypes, the type of corresponding column names + */ + result CreateTable(const Tizen::Base::String& tableName, Tizen::Base::Collection::ArrayList* pColumnNames, Tizen::Base::Collection::ArrayList* pColumnTypes); + + /** + * Deletes records from the table + * + * @return E_SUCCESS in case of success else system wide error code + * @param[in] tableName, the table name from which the rows to be deleted + * @param[in] whereCondition, the criteria to select the correct row to be modified + */ + result DeleteFromTable(const Tizen::Base::String& tableName, const Tizen::Base::String& whereCondition); + + /** + * Reads data from the database. + * + * @return E_SUCCESS in case of success else system wide error code + * @param[in] tableName, the table name from which the rows to be deleted + * @param[in] whereCondition, the criteria to select the correct row to be modified + * @param[out] the retrieved data, the column name to be keys and values as value. + */ + result GetDataRowFromTable(const Tizen::Base::String& tableName, const Tizen::Base::String& whereCondition, Tizen::Base::Collection::HashMap& rowDataHashMap); + + /** + * Returns the last added records recordId, + * this record id is the value of the PRIMARY AutoIncremented column in the table + * + * @return int, the value of record id. + * @param[in] tableName, table name for which the record id has to be fetched + * + * @remark : if fails it returns -1 and the error can be fetched using GetLastResult() Method + */ + int GetLastAddedRowID(const Tizen::Base::String& tableName); + + /** + * Inserts the data in given table. + * + * @return E_SUCCESS in case of success else system wide error code + * @param[in] tableName, name of the table to be created. + * @param[in] pColumnNames, the names for each columns in the table + * @param[in] pColumnTypes, the type of corresponding columns + * @param[in] pColumnValues, the values for corresponding columns + */ + result InsertToTable(const Tizen::Base::String& tableName, Tizen::Base::Collection::ArrayList* pColumnNames, Tizen::Base::Collection::ArrayList* pColumnTypes, Tizen::Base::Collection::ArrayList* pColumnValues); + + /** + * Inserts the data in given table. + * + * @return E_SUCCESS in case of success else system wide error code + * @param[in] tableName, name of the table to be created. + * @param[in] pColumnsToModify, the column names which needs to be updated + * @param[in] pColumnTypes, the type of corresponding columns + * @param[in] pColumnsNewData, the values for corresponding columns + * @param[in] whereCondition, the criteria to select the correct row to be modified + */ + result UpdateTable(const Tizen::Base::String& tableName, Tizen::Base::Collection::ArrayList* pColumnsToModify, Tizen::Base::Collection::ArrayList* pColumnTypes, Tizen::Base::Collection::ArrayList* pColumnsNewData, const Tizen::Base::String* pWhereCondition); + +private: + /** + * Destructor + * This destructor is intentionally declared as private to implement the Singleton semantic. + */ + ~GenericDatabaseManager(void); + + /** + * Constructor + * This Constructor is intentionally declared as private to implement the Singleton semantic. + */ + GenericDatabaseManager(void); + + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + GenericDatabaseManager(const GenericDatabaseManager&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + GenericDatabaseManager& operator =(const GenericDatabaseManager&); + + /** + * Creates the singleton object of HomeDatabaseManager + */ + static void CreateInstance(void); + + /** + * Destroys the singleton object of HomeDatabaseManager + */ + static void DestroyInstance(void); + + /** + * returns the column type of the mentioned column name + * + * @return DbColumnType, tells about the data type of the column. + * @param[in] columnName, column name for which type is to be known. + */ + Tizen::Io::DbColumnType GetColumnType(Tizen::Io::DbEnumerator* pDbEnumerator, Tizen::Base::String* pColumnName); + + /** + * returns the columntype of the mentioned columnName + * + * @return int, tells about the datatype of the column. + * @param[in] pColumnName, column name for which type is to be known. + */ + int GetColumnIndex(Tizen::Io::DbEnumerator* pDbEnumerator, Tizen::Base::String* pColumnName); + +private: + static GenericDatabaseManager* __pDatabaseManager; // singleton object of this class + Tizen::Io::Database* __pDatabase; // database instance +}; + +#endif //_HM_GENERIC_DATABASE_MANAGER_H_ diff --git a/inc/HmHomeApp.h b/inc/HmHomeApp.h new file mode 100644 index 0000000..9485952 --- /dev/null +++ b/inc/HmHomeApp.h @@ -0,0 +1,79 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomeApp.h + * @brief Keeps declaration of UiApp derived class. + */ + +#ifndef _HM_HOME_APP_H_ +#define _HM_HOME_APP_H_ + +#include +#include + +class HomeForm; +class HomePresentationModel; + +/** + * @class HomeApp + * @brief UiApp must inherit from UiApp class + * which provides basic features necessary to define an UiApp. + */ +class HomeApp + : public Tizen::App::UiApp + , public Tizen::System::IScreenEventListener +{ +public: + /** + * UiApp must have a factory method that creates an instance of itself. + */ + static Tizen::App::UiApp* CreateInstance(void); + +public: + /** + * Constructor + * Initializes the object with default values + */ + HomeApp(void); + + /* + * desctructor + * used to free allocated resources + */ + virtual ~HomeApp(void); + +public: + bool OnAppInitializing(Tizen::App::AppRegistry& appRegistry); + bool OnAppInitialized(void); + bool OnAppWillTerminate(void); + bool OnAppTerminating(Tizen::App::AppRegistry& appRegistry, bool forcedTermination = false); + void OnLowMemory(void); + void OnBatteryLevelChanged(Tizen::System::BatteryLevel batteryLevel); + void OnScreenOn(void); + void OnScreenOff(void); + void OnUserEventReceivedN(RequestId requestId, Tizen::Base::Collection::IList* pArgs); + + void OnForeground(void); + void OnBackground(void); + +private: + bool __presentationModelInitialized; //Indicates if the Model is initialized on not + HomeForm* __pHomeForm; //the object of Form to be shown for this application + HomePresentationModel* __pPresentationModel; //the Model instance +}; + +#endif //_HM_HOME_APP_H_ diff --git a/inc/HmHomeForm.h b/inc/HmHomeForm.h new file mode 100644 index 0000000..be67121 --- /dev/null +++ b/inc/HmHomeForm.h @@ -0,0 +1,162 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomeForm.h + * @brief Keeps declaration of Main Form for the application + */ + +#ifndef _HM_HOME_FORM_H_ +#define _HM_HOME_FORM_H_ + +#include +#include +#include "HmCustomPageControl.h" +#include "HmCustomPageMarker.h" +#include "HmHomePresentationModel.h" +#include "HmICustomPageControlEventListener.h" +#include "HmIPageControlItemProvider.h" + +class HomeItemInfo; +class ProgressPanel; + +/** + * @class HomeForm + * @brief The form class for this application, it represents the Home Screen + */ +class HomeForm + : public Tizen::Ui::Controls::Form + , public Tizen::System::ISettingEventListener + , public Tizen::Ui::ITouchEventListener + , public ICustomPageControlEventListener + , public ICustomPageMarkerEventListener + , public IHomePresentationModelEventListener + , public IPageControlItemProvider +{ +public: + /** + * Constructor + */ + HomeForm(void); + + /** + * Destructor + */ + virtual ~HomeForm(void); + + /** + * Called when we need to initialize the Form + */ + bool Initialize(void); + + /** + * Creates and initializes Page controls + */ + result InitializePageControls(HomePresentationModel* pPresentationModel); + + /** + * Updates all the pages in the Home Screen + */ + void UpdateAllPages(void); + + /** + * Updates pages in home screen + */ + void UpdatePage(Tizen::Base::Collection::ArrayList* pArgs); + +public: + //methods from Form + virtual result OnInitializing(void); + virtual result OnTerminating(void); + + // From ISettingEventListener + virtual void OnSettingChanged(Tizen::Base::String& key); + + // from ITouchEventListener + virtual void OnTouchPressed(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchReleased(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + virtual void OnTouchMoved(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchFocusIn(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchFocusOut(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + virtual void OnTouchCanceled(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) {} + + // from ICustomPageControlEventListener + // Called when any page gets swept, this method gets called. + virtual void OnPageSwept(int pageNumber); + + // Called when a new page gets added in the Page Control + virtual void OnPageAdded(int pageNumber); + + // Called when a new page gets deleted in the Page Control + virtual void OnPageRemoved(int pageNumber); + + // from ICustomPageMarkerEventListener + // Called when any bubble in the Page Marker gets pressed + virtual void OnMarkerBubbleMoved(int bubbleNumber); + + //from IHomePresentationModelEventListener + // Called when Installation completed successfully + virtual void OnInstallationCompleted(const HomeItemInfo& pItemInfo); + + // Called when an un-install request occures + virtual void OnAppUninstallRequested(HomeItemInfo* pItemInfo); + + // Called when Un-Installation completed successfully + virtual void OnUnInstallationCompleted(const HomeItemInfo& pItemInfo); + + // Called, when it needs to update some pages + virtual void OnUpdatePageRequestedN(Tizen::Base::Collection::ArrayList* pPageList); + + // from IPageControlItemProvider + /** + * Returns the total number of pages + */ + virtual int GetPageCount(void); + + /** + * Returns the number of items, which belongs to the mentioned page + */ + virtual int GetItemCount(int pageNumber); + + /** + * Returns the actual item pointer, at the mentioned position + */ + virtual HomeItemInfo* GetItem(int pageNumber, int index); + + /** + * Rearranges the items within a page, across page and moved icons. + */ + virtual void RearrangeItems(HomeItemInfo* pMovedAppInfo, int newPageNumber, int newIndex); + +private: + bool __isEditEnabled; //indicates if the Home screen is in edit mode. + bool __isLanguageChanged; + CustomPageControl* __pPageControl; // PageControl instance + CustomPageMarker* __pPageMarker; // PageMarker instance + HomePresentationModel* __pHomePresentationModel; // HmHomePresentationModel instance + ProgressPanel* __pProgressPanel; //Progress panel + Tizen::Base::String __currentLanguage; + Tizen::Graphics::Bitmap* __pBackgroundBitmap; //the background bitmap + Tizen::Graphics::Bitmap* __pSettingsBitmap; //The setting button bitmap + Tizen::Graphics::Bitmap* __pSettingsPressedBitmap; //The pressed setting button bitmap + Tizen::Ui::Controls::Label* __pBackgroundLabel; // the background label to show the wallpaper + Tizen::Ui::Controls::Panel* __pSettingsPanel; // the setting panel + + + +}; + +#endif //_HM_HOME_FORM_H_ diff --git a/inc/HmHomeItemInfo.h b/inc/HmHomeItemInfo.h new file mode 100644 index 0000000..8741163 --- /dev/null +++ b/inc/HmHomeItemInfo.h @@ -0,0 +1,163 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomeItemInfo.h + * @brief Keeps declaration of the HomeItemInfo + * Declares the HomeItemInfo class, it keeps the information of all the applications installed. + */ + +#ifndef _HM_HOME_APP_INFO_H_ +#define _HM_HOME_APP_INFO_H_ + +#include +#include + +/** + * @class HomeItemInfo + * @brief Keeps all the informations of the applications. + */ +class HomeItemInfo + : public Tizen::Base::Object +{ +public: + /** + * Constructor + */ + HomeItemInfo(void); + + /** + * Destructor + */ + virtual ~HomeItemInfo(void); + + /** + * Returns applications ID + * + * @return Tizen::Base::String, Application's id + */ + Tizen::Base::String GetAppId(void) const; + + /** + * returns the application icon, the bitmap object to shown in the screen + * + * @return Bitmap*, the bitmap object for app icon + */ + Tizen::Graphics::Bitmap* GetApplicationIcon(void) const; + + /** + * Returns applications Name + * + * @return Tizen::Base::String*, Application's Name + */ + Tizen::Base::String GetAppName(void) const; + + /** + * tell about, the application's icon path + * + * @return bool, true if can be shown in Home else false. + */ + Tizen::Base::String GetIconPath(void) const; + + /** + * Returns package ID + * + * @return Tizen::Base::String, Package's id + */ + Tizen::Base::String GetPackageId(void) const; + + /** + * Gets the position of the application's icon in the home screen. + * + * @param[out] pageNumber, the page number + * @param[out] position, position in that page + */ + void GetPositionInHomeScreen(int& pageNumber, int& position) const; + + /** + * Initializes data by fetching information from the PackageInfo + * + * @return E_SUCCESS, otherwise standard error code + * @param[in] pPackInfo, the information of the package + */ + result Initialize(Tizen::App::Package::PackageAppInfo* pPackAppInfo, Tizen::App::Package::PackageInfo* pPackInfo); + + /** + * tells about, if the application can be uninstalled or not + * + * @return bool, true if can be uninstalled else false. + */ + bool IsUnistallable(void) const; + + /** + * tell about, if the app icon can be shown in the home screen + * + * @return bool, true if can be shown in Home else false. + */ + bool IsVisibleInMainMenu(void) const; + + /** + * sets the application icon, the bitmap object to shown in the screen + * + * @param[in] pBitmap, the bitmap object for app icon + */ + void SetApplicationIcon(Tizen::Graphics::Bitmap* pAppIconBitmap); + + /** + * sets the application name + * + * @param[in] newAppName, the name for this application + */ + void SetApplicationName(Tizen::Base::String& newAppName); + /** + * Sets the index of this item + * + * @param[in] newIndex, the new index for this application + */ + void SetItemIndex(int newIndex); + + /** + * Sets the position of the app icon in the home screen + * + * @param[in] pageNumber, the page number + * @param[in] position, position in that page + */ + void SetPositionInHomeScreen(int pageNumber, int position); + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + HomeItemInfo(const HomeItemInfo&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + HomeItemInfo& operator =(const HomeItemInfo&); + +private: + bool __isVisibleInMainMenu; // can be shown in the home screen + bool __isUninstallable; // can be un-installed + int __pageNumber; //Page number of this application in home screen + int __position; // position of the application in home screen page + Tizen::Base::String __appId; //application ID + Tizen::Base::String __appIconPath; // Application's Icon Path + Tizen::Base::String __appName; //Application name + Tizen::Graphics::Bitmap* __pAppIcon; // decoded bitmap for the application Icon + Tizen::Base::String __packageId; //package ID +}; + +#endif //_HM_HOME_APP_INFO_H_ diff --git a/inc/HmHomePresentationModel.h b/inc/HmHomePresentationModel.h new file mode 100644 index 0000000..f461362 --- /dev/null +++ b/inc/HmHomePresentationModel.h @@ -0,0 +1,236 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomePresentationModel.h + * @brief Keeps declaration of the HomePresentationModel + * Declares the HomePresentationModel classe, it keeps the data required to show the application icons in the home view + */ + + +#ifndef _HM_HOME_PRESENTATION_MODEL_H_ +#define _HM_HOME_PRESENTATION_MODEL_H_ + +#include +#include "HmGenericDatabaseManager.h" +#include "HmIHomePresentationModelListener.h" +#include "HmIPackageInfoListListener.h" +#include "HmPackageInfoListRetrieveThread.h" +#include "HmTypes.h" + +class HomeItemInfo; +class PackageInfoListRetrieveThread; + +/** + * @enum HomePresentationRequestIds + * Request IDs to the Model Thread + */ +enum HomePresentationModelRequestTypes +{ + MODEL_REQUEST_INITIALIZE = 100, /** Initialization request */ +}; + +/** + * @class HomePresentationModel + * @brief Home data presenter + */ + +class HomePresentationModel + : public Tizen::Base::Object + , public Tizen::App::Package::IPackageInstallationEventListener + , public IPackageInfoListListener +{ + + class HomeApplicationsComparer + : public Tizen::Base::Collection::IComparer + { + public: + virtual result Compare(const Tizen::Base::Object& obj1, const Tizen::Base::Object& obj2, int& cmp) const; + }; + +public: + /** + * The default constructor for the class + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor + */ + HomePresentationModel(void); + + /** + * This is the destructor for this class. + */ + virtual ~HomePresentationModel(void); + + /** + * Constructs the model, initializes the members with proper values + * + * @return result, E_SUCCESS or standard error code if failed. + */ + result Construct(void); + + /** + * Returns the item instance to be shown in mentioned position + * + * @return HomeItemInfo*, the pointer to the actual item. + * @param[in] page Number, the page number to which the Item belongs + * @param[in] index, The index for which the item is to be retrieved + */ + HomeItemInfo* GetItem(int pageNumber, int index) const; + + /** + * Returns the number of items in the mentioned page + * + * @return int, number of items in page. + * @param[in] pageNumber, the page number for which the Item count needed + */ + int GetItemCount(int pageNumber) const; + + /** + * Returns the number of pages to be created to show all the application icons + * + * @return int, number of pages. + */ + int GetPageCount(void) const; + + /** + * Updates the application informations etc in case of language changed + */ + void LanguageChanged(void); + + /** + * Rearranges the items within a page, across page and moves icons . + * + * @param[in] pMovedAppInfo, The HomeItemInfo's pointer, which has to be moved + * @param[in] newPageNumber, New Page number, where the icon has to be placed + * @param[in] newIndex, The index to which the mentioned application to be placed + */ + void RearrangeItems(HomeItemInfo* pMovedAppInfo, int newPageNumber, int newIndex); + + /** + * Sets the installation/un-installation event listener. + * + * @param[in] pListener, the listener object to be set. + */ + void SetHomePackageEventListener(IHomePresentationModelEventListener* pListener); + + /** + * Updates the applications data into the database. + * + * @return E_SUCCESS, in case of success else system wide error code. + */ + result UpdatePageData(void); + + //from IPackageInstallationEventListener + virtual void OnPackageInstallationCompleted(const Tizen::App::PackageId& packageId, Tizen::App::Package::PackageInstallationResult installationResult); + virtual void OnPackageInstallationInProgress(const Tizen::App::PackageId& packageId, int progress) {} + virtual void OnPackageUninstallationCompleted(const Tizen::App::PackageId& packageId, bool uninstallationResult); + + //from IPackageInfoListListener + /** + * Called when PackageListing completes + * + * @param[in] pAppsList, list of installed packages + * @param[in] totalApps, total number of installed applications + * @param[in] totalPages, total number of pages + */ + virtual void OnPackageInfoRetrievedN(Tizen::Base::Collection::HashMap* pAppsList, int totalApps, int totalPages); + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + HomePresentationModel(const HomePresentationModel&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + HomePresentationModel& operator =(const HomePresentationModel&); + + /** + * Tries to find a HomeItemInfo with the name sa provided in parameters + * + * @return HomeItemInfo*, valid pointer if found else null + * @param[in] packageId, the packageId to be searched for + */ + HomeItemInfo* FindAppObjectInList(const Tizen::Base::String& packageIdToFind); + + /** + * Initializes the DataBase with initial values, create databse and tables if not already created. + * + * @return E_SUCCESS, in case of success else system wide error code. + */ + result InitializeDatabase(void); + + /** + * Inserts page position data into the database. + * + * @return E_SUCCESS, in case of success else system wide error code. + * @param[in] pItemInfo, the application object to get the data from. + */ + result InsertPageDataInDataBase(const HomeItemInfo* pItemInfo); + + /** + * Notify the ui about the package manager installation event + * + * @return result, E_SUCCESS, in case of success else system wide error code. + * @param[in] appId, the application id for which installation completed + */ + result NotifyInstallationEvent(const Tizen::App::PackageId& packageId); + + /** + * this api prepares the application list, by using data in database, to retain the previous state. + * + * @return, E_SUCCESS, in case of success else system wide error code. + */ + result PrepareApplicationsList(void); + + /** + * Sorts the pages, depending upon the position of the application icons + */ + void SortPages(void); + + /** + * Updates the applications information into the database table. + * @return E_SUCCESS, in case of success else system wide error code. + * @param[in] pItemInfo, the application object to get the data from. + */ + result UpdateDataToDatabase(HomeItemInfo* pItemInfo); + + /** + * Update the applications info objects within the mentioned ArrayList, with corresponding postions + * Gets called, after re-arrangement completes. + */ + void UpdatePositions(Tizen::Base::Collection::ArrayList& pAppListToUpdate); + + /** + * Reads the database and updates the local copy of the applications information + * + * @return E_SUCCESS, in case of success else system wide error code. + */ + result UpdateWithPositions(void); + +private: + GenericDatabaseManager* __pDataBaseManager; // HmDatabaseManager instance. + HomeApplicationsComparer __comparerObject; // IComparer derived class to be passed in Sort method + IHomePresentationModelEventListener* __pDataListener; // listener for various events + int __totalApps; //total number of applications + int __totalPages; //total number of pages + Tizen::App::Package::PackageManager* __pPackMgr; //PackageManager instance + Tizen::Base::Collection::HashMap* __pAppHashMap; // application informations + PackageInfoListRetrieveThread* __pPackageInfoRetrieveThread; // the worker thread instance to fetch packages list +}; + +#endif //_HM_HOME_PRESENTATION_MODEL_H_ diff --git a/inc/HmICustomPageControlEventListener.h b/inc/HmICustomPageControlEventListener.h new file mode 100644 index 0000000..9f8a052 --- /dev/null +++ b/inc/HmICustomPageControlEventListener.h @@ -0,0 +1,69 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmICustomPageControlEventListener.h + * @brief Listener interface for CustomPageControl events + */ + +#ifndef _HM_ICUSTOM_PAGE_CONTROL_EVENT_LISTENER_H_ +#define _HM_ICUSTOM_PAGE_CONTROL_EVENT_LISTENER_H_ + +class HomeItemInfo; + +/** + * @class ICustomPageControlEventListener + * @brief Notifies about the events occurred in page control * + */ + +class ICustomPageControlEventListener +{ +public: + /** + * This polymorphic destructor should be overridden if required. + * This way, the destructor of the derived classes are called when the + * destructor of this interface is called + */ + virtual ~ICustomPageControlEventListener(void) {} + + /** + * This method gets called when Uninstall of an application requested + * @param[in] pItemInfo, the application's information to be un-installed + */ + virtual void OnAppUninstallRequested(HomeItemInfo* pItemInfo) = 0; + + /** + * This method gets called when a new page gets added. + */ + virtual void OnPageAdded(int pageNumber) = 0; + + /** + * This method gets called when the page gets deleted + * @param[in] pageNumber, gives the deleted page number + */ + virtual void OnPageRemoved(int pageNumber) = 0; + + /** + * This method gets called when the page gets swept or scrolled + * + * @param[in] pageNumber, gives the currently shown page number + */ + virtual void OnPageSwept(int pageNumber) = 0; + +}; + + +#endif // _HM_ICUSTOM_PAGE_CONTROL_EVENT_LISTENER_H_ diff --git a/inc/HmICustomPageMarkerEventListener.h b/inc/HmICustomPageMarkerEventListener.h new file mode 100644 index 0000000..a72e53e --- /dev/null +++ b/inc/HmICustomPageMarkerEventListener.h @@ -0,0 +1,47 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmICustomPageMarkerEventListener.h + * @brief Listener interface for CustomPageMarker control events + */ + +#ifndef _HM_ICUSTOM_PAGE_MARKER_EVENT_LISTENER_H_ +#define _HM_ICUSTOM_PAGE_MARKER_EVENT_LISTENER_H_ + +/** + * @class ICustomPageMarkerEventListener + * @brief Event listener for the marker bubbles + */ +class ICustomPageMarkerEventListener +{ +public: + /** + * This polymorphic destructor should be overridden if required. + * This way, the destructor of the derived classes are called when the + * destructor of this interface is called + */ + virtual ~ICustomPageMarkerEventListener(void) {} + + /** + * Notifies about the currently selected bubble. + * + * @param[in] bubbleNo, the bubble number which got selected. + */ + virtual void OnMarkerBubbleMoved(int bubbleNo) = 0; +}; + +#endif // _HM_ICUSTOM_PAGE_MARKER_EVENT_LISTENER_H_ diff --git a/inc/HmIHomePresentationModelListener.h b/inc/HmIHomePresentationModelListener.h new file mode 100644 index 0000000..84f7e5b --- /dev/null +++ b/inc/HmIHomePresentationModelListener.h @@ -0,0 +1,69 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmIHomePresentationModelListener.h + * @brief keeps the declaration for IHomePresentationModelEventListener, + * which contains the event callback methods for HomePresentationModel events. + */ + +#ifndef _HM_IHOME_PRESENTATION_MODEL_LISTENER_H_ +#define _HM_IHOME_PRESENTATION_MODEL_LISTENER_H_ + +/** + * @class IHomePresentationModelEventListener + * @brief Event listener for the Model events + */ +class IHomePresentationModelEventListener +{ +public: + /** + * This polymorphic destructor should be overridden if required. + * This way, the destructors of the derived classes are called when the + * destructor of this interface is called + */ + virtual ~IHomePresentationModelEventListener(void) {} + + /** + * Installation completed successfully + * + * @param[in] Info, application info of the installed application + */ + virtual void OnInstallationCompleted(const HomeItemInfo& pItemInfo) = 0; + + /** + * Installation is in progress + * + * @param[in] Info, application info of the application being installed. + */ + virtual void OnInstallationInProgress(const HomeItemInfo& pInfo, int progress) {} + + /** + * Un-Installation completed successfully + * + * @param[in] Info, application info of the un-installed application + */ + virtual void OnUnInstallationCompleted(const HomeItemInfo& pItemInfo) = 0; + + /** + * Installation completed successfully + * + * @param[in] Info, application info of the installed application + */ + virtual void OnUpdatePageRequestedN(Tizen::Base::Collection::ArrayList* pPageList) = 0; + +}; +#endif //_HM_IHOME_PRESENTATION_MODEL_LISTENER_H_ diff --git a/inc/HmIPackageInfoListListener.h b/inc/HmIPackageInfoListListener.h new file mode 100644 index 0000000..bda57cc --- /dev/null +++ b/inc/HmIPackageInfoListListener.h @@ -0,0 +1,53 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmIPackageListRetriverListener.h + * @brief Listener interface for PackageListRetrieverThread + */ + +#ifndef _HM_IPACKAGE_INFO_LIST_LISTENER_H_ +#define _HM_IPACKAGE_INFO_LIST_LISTENER_H_ + +#include + +/** + * @class IPackageRetriverListener + * @brief the listener class to notify about completion of package listing. + */ +class IPackageInfoListListener +{ +public: + /** + * This polymorphic destructor should be overridden if required. + * This way, the destructors of the derived classes are called when the + * destructor of this interface is called + */ + virtual ~IPackageInfoListListener(void) {} + + /** + * Called when Package informations of installed packages completes. + * + * @param[in] pAppsList, the list of installed applications + * @param[in] totalApps, total number of installed applications + * @param[in] totalPages, total number of pages to be created + */ + virtual void OnPackageInfoRetrievedN(Tizen::Base::Collection::HashMap* pAppsList, int totalApps, int totalPages) = 0; +}; + + + +#endif // _HM_IPACKAGE_INFO_LIST_LISTENER_H_ diff --git a/inc/HmIPageControlItemProvider.h b/inc/HmIPageControlItemProvider.h new file mode 100644 index 0000000..9b48c83 --- /dev/null +++ b/inc/HmIPageControlItemProvider.h @@ -0,0 +1,76 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmIPageControlItemProvider.h + * @brief Keeps declaration of the IPageControlItemProvider + * The class keeps necessary methods which can be used for creating items for the Page data control. + */ + +#ifndef _HM_IPAGE_CONTROL_ITEM_PROVIDER_H_ +#define _HM_IPAGE_CONTROL_ITEM_PROVIDER_H_ + +class HomeItemInfo; + +/** + * @class IPageControlItemProvider + * @brief declares of the IPageControlItemProvider + * The class keeps necessary methods which can be used for creating items for the PageControl. + */ +class IPageControlItemProvider +{ +public: + /** + * This polymorphic destructor should be overridden if required. + * This way, the destructors of the derived classes are called when the destructor of this interface is called. + */ + virtual ~IPageControlItemProvider(void) {} + + /** + * Returns the actual item pointer, at the mentioned position + * + * @return HomeItemInfo*, The actual item's pointer + * @param[in] pageNumber, page number in which the item to be located + * @param[in] index, The index for which the item to be retrieved + */ + virtual HomeItemInfo* GetItem(int pageNumber, int index) = 0; + + /** + * Returns the number of items, which belongs to the mentioned page + * + * @return int, The number of items in the page + * @param[in] pageNumber, Page number + */ + virtual int GetItemCount(int pageNumber) = 0; + + /** + * Returns the total number of pages + * + * @return int, the number of pages + */ + virtual int GetPageCount(void) = 0; + + /** + * Rearranges the items within a page, across page and moved icons. + * + * @param[in] pMovedAppInfo, The HomeItemInfo's pointer, which has to be moved + * @param[in] newPageNumber, New Page number, where the icon has to be placed + * @param[in] newIndex, The index to which the mentioned application to be placed + */ + virtual void RearrangeItems(HomeItemInfo* pMovedAppInfo, int newPageNumber, int newIndex) = 0; +}; + +#endif // _HM_IPAGE_CONTROL_ITEM_PROVIDER_H_ diff --git a/inc/HmMainFrame.h b/inc/HmMainFrame.h new file mode 100644 index 0000000..355283f --- /dev/null +++ b/inc/HmMainFrame.h @@ -0,0 +1,52 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmMainFrame.h + * @brief Keeps declaration of Main Frame for the application + */ + +#ifndef _HM_HOME_FRAME_H_ +#define _HM_HOME_FRAME_H_ + +#include +#include + +/** + * @class MainFrame + * @brief This is Frame for the application. + */ +class MainFrame + : public Tizen::Ui::Controls::Frame +{ +public: + /** + * Constructor + */ + MainFrame(void); + + /** + * Destructor + */ + virtual ~MainFrame(void); + +public: + // from Frame + virtual result OnInitializing(void); + virtual result OnTerminating(void); +}; + +#endif //_HM_HOME_FRAME_H_ diff --git a/inc/HmPackageInfoListRetrieveThread.h b/inc/HmPackageInfoListRetrieveThread.h new file mode 100644 index 0000000..ebaa0d0 --- /dev/null +++ b/inc/HmPackageInfoListRetrieveThread.h @@ -0,0 +1,73 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file PackageInfoListRetrieveThread.h + * @brief The file contains declaration of PackageInfoListRetrieveThread, + * which is a worker thread and being used to retrieve the list PackageInfos, for the Applications installed on device. + */ + +#ifndef _HM_PACKAGE_INFO_LIST_RETRIEVE_THREAD_H_ +#define _HM_PACKAGE_INFO_LIST_RETRIEVE_THREAD_H_ + +#include +#include "HmIPackageInfoListListener.h" + +/** + * @class PackageInfoListRetrieveThread + * @brief The worker thread class for retriving and listing of various types of packages. + */ +class PackageInfoListRetrieveThread + : public Tizen::Base::Runtime::Thread +{ +public: + /** + * Constructor + */ + PackageInfoListRetrieveThread(IPackageInfoListListener* pPackageListener); + + /** + * Destructor + */ + virtual ~PackageInfoListRetrieveThread(void); + + /** + * Starts this Thread, for listing specified type of packages. + * + * @return result, E_SUCCESS if thread starts properly, else system wide error code. + * @param[in] typeOfInstall, tells of which kind of packages to be listed. + */ + result SetPackageType(void); + + //this method gets called when the thread is created without an IRunnable instance. In this thread it lists the specified type of packages. + virtual Tizen::Base::Object* Run(void); + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + PackageInfoListRetrieveThread(const PackageInfoListRetrieveThread&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + PackageInfoListRetrieveThread& operator =(const PackageInfoListRetrieveThread&); + +private: + IPackageInfoListListener* __pPackageListener; //The listener to listen about the completion of package listing +}; + +#endif //_HM_PACKAGE_INFO_LIST_RETRIEVE_THREAD_H_ diff --git a/inc/HmProgressPanel.h b/inc/HmProgressPanel.h new file mode 100644 index 0000000..0feca96 --- /dev/null +++ b/inc/HmProgressPanel.h @@ -0,0 +1,80 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmProgressPanel.h + * @brief Keeps declaration of ProgressPanel Implementation + */ + +#ifndef _HM_HOME_PROGRESS_PANEL_H_ +#define _HM_HOME_PROGRESS_PANEL_H_ + +#include + +/** + * @class ProgressPanel + * @brief Keeps the required functions and objects in showing a wait cursor + */ +class ProgressPanel + : public Tizen::Ui::Controls::Panel +{ + +public: + /** + * default Constructor + * The object is not fully constructed after this constructor is called. + * For full construction, the Construct() method must be called right after calling this constructor + */ + ProgressPanel(void); + + /** + * Destructor + * Handles all the deallocations and cleanup tasks reuired for this object + */ + virtual ~ProgressPanel(void); + + /** + * Second phase of Construction + */ + result Construct(const Tizen::Graphics::Rectangle& controlRectangle); + + /** + * Start animating the wait cursor + */ + result StartAnimation(void); + + /** + * Stops the running animations + */ + result StopAnimation(void); + +private: + /** + * The implementation of this copy constructor is intentionally blank and declared as private to prohibit copying of objects. + */ + ProgressPanel(const ProgressPanel&); + + /** + * The implementation of this copy assignment operator is intentionally blank and declared as private to prohibit copying of objects. + */ + ProgressPanel& operator =(const ProgressPanel&); + +private: + Tizen::Base::Collection::ArrayList* __pAnimationFrameList; // The list of AnimationFrames + Tizen::Ui::Controls::Animation* __pAnimation; // The animation control +}; + +#endif //_HM_HOME_PROGRESS_PANEL_H_ diff --git a/inc/HmTypes.h b/inc/HmTypes.h new file mode 100644 index 0000000..898275e --- /dev/null +++ b/inc/HmTypes.h @@ -0,0 +1,118 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmTypes.h + * @brief Keeps all the constants used throughout the application + */ + +#ifndef _HM_TYPES_H_ +#define _HM_TYPES_H_ + +// string constants +// bitmap paths +extern const wchar_t* IDB_BACKGROUND_IMAGE; +extern const wchar_t* IDB_CLOSE_ICON; +extern const wchar_t* IDB_SELECTED_BUBBLE_TOP; +extern const wchar_t* IDB_BUBBLE_TOP; +extern const wchar_t* IDB_DEFAULT_APP_ICON; +extern const wchar_t* IDB_SETTING_BUTTON; +extern const wchar_t* IDB_SETTING_BUTTON_PRESSED; +// application specific constants +extern const wchar_t* SETTINGS_KEY_WALLPAPER; +extern const wchar_t* SETTINGS_KEY_LANGUAGE; +extern const wchar_t* WAIT_CURSOR_IMAGE_BASE; +extern const wchar_t* BITMAP_EXTENSION; +extern const wchar_t* APP_ID_REPLACE_STR; +extern const wchar_t* SETTING_ANIMATION_PROPERTY_NAME; +// database constants +extern const wchar_t* HOME_DATABASE_NAME; +// database table names +extern const wchar_t* HOME_APPLICATIONS_TABLE; +// database column names +extern const wchar_t* APPS_RECORD_ID; +extern const wchar_t* APPS_APP_ID; +extern const wchar_t* APPS_APP_NAME; +extern const wchar_t* APPS_APP_ICON; +extern const wchar_t* APPS_APP_PAGE; +extern const wchar_t* APPS_APP_PAGEINDEX; +//DATATYPES used for database +extern const wchar_t* DATATYPE_INTEGER_PRIMARY; +extern const wchar_t* DATATYPE_INTEGER; +extern const wchar_t* DATATYPE_TEXT; +extern const wchar_t* DATATYPE_UNIQUE; +// database queries +extern const wchar_t* CREATE_TABLE; +extern const wchar_t* INSERT_TABLE; +extern const wchar_t* SELECT_TABLE; +extern const wchar_t* DELETE_TABLE; +extern const wchar_t* UPDATE_TABLE; +extern const wchar_t* GET_LAST_RECORD_ID; + +extern const unsigned int COLOR_SETTING_BOUNDARY_INNER; + +// int constants +// Ui Bounds +extern const int X_MARKER_LABEL_OFFSET; +extern const int X_MARKER_POSITION; +extern const int Y_MARKER_POSITION; +extern const int W_MARKER_LABEL; +extern const int H_MARKER_LABEL; +extern const int W_MARKER_OFFSET; +extern const int X_PAGE_POSITION; +extern const int H_APP_CAPTION_TEXT; +extern const int Y_APP_ICON_IMAGE_START; +extern const int W_APPLICATION_ICON; +extern const int H_APPLICATION_ICON; +extern const int X_PAGE_OFFSET; +extern const int H_EDIT; +extern const int H_CONTROL_OFFSET; +extern const int H_PAGE_MARKER; +extern const int W_DEFAULT_PAGE; +extern const int X_SETTING_PANEL; +extern const int Y_SETTING_PANEL; +extern const int W_SETTING_PANEL; +extern const int H_SETTING_PANEL; +extern const int X_SETTING_PANEL_PRESSED_OFFSET; +extern const int SIZE_SETTING_LABEL_OFFSET; +extern const int OVERLAY_BITMAP_DIMENSION; +extern const int GAP_ICON_HORIZONTAL; +extern const int GAP_ICON_VERTICAL; +extern const int WAIT_CURSUR_DIMESION; +extern const int APP_ICON_IMAGE_SIZE; +// timer durations +extern const int DURATION_FOR_EACH_IMAGE; +extern const int DURATION_SETTING_ANIMATION; +extern const int MOVEMENT_UPDATE_DURATION; +extern const int LONG_TOUCH_GESTURE_DURATION; +extern const int SCROLL_ANIMATION_DURATION; +// font size +extern const int FONT_SIZE_APP_CAPTION; +// color values +extern const unsigned int COLOR_APP_ICON_CAPTION; +extern const unsigned int COLOR_APP_CAPTION_SHADOW1; +extern const unsigned int COLOR_APP_CAPTION_SHADOW2; +// action ids +extern const int IDA_OVERLAYBITMAP_CLOSE; +extern const int IDA_SETTING_BUTTON; +// other constants +extern const int MAX_ICONS_PER_PAGE; +extern const int MAX_PAGE_COUNT; +extern const int MAX_BITMAP_COUNT; +extern const int REPEAT_COUNT; +extern const int MOVING_ICON_OPACITY; + +#endif //_HM_TYPES_H_ diff --git a/manifest.xml b/manifest.xml new file mode 100644 index 0000000..5826edd --- /dev/null +++ b/manifest.xml @@ -0,0 +1,34 @@ + + + cwkuromqdr + 1.0.0 + C++App + + + + + + + + 2.0 + + http://tizen.org/privilege/application.launch + http://tizen.org/privilege/packageinfo + http://tizen.org/privilege/packagemanager.install + http://tizen.org/privilege/packagesetting + + + + + + Home-Ref + + + mainmenu.png + + + + + + + diff --git a/packaging/apps.Home.spec b/packaging/apps.Home.spec new file mode 100755 index 0000000..17cea2b --- /dev/null +++ b/packaging/apps.Home.spec @@ -0,0 +1,62 @@ +Name: apps.Home +Summary: Home application +Version: 1.0.0 +Release: 1 +Group: TO_BE/FILLED_IN +License: TO BE FILLED IN +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(osp-appfw) +BuildRequires: pkgconfig(osp-uifw) +BuildRequires: osp-appfw-internal-devel +BuildRequires: osp-uifw-internal-devel +BuildRequires: pkgconfig(osp-uifw) +BuildRequires: osp-uifw-internal-devel +BuildRequires: pkgconfig(osp-media) +BuildRequires: osp-media-internal-devel +BuildRequires: pkgconfig(osp-image) +BuildRequires: osp-media-internal-devel +BuildRequires: pkgconfig(osp-net) +BuildRequires: osp-net-internal-devel +BuildRequires: pkgconfig(osp-image-core) + +Requires: osp-installer + +%description +Verification application: Home + +%prep +%setup -q + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +%ifarch %{ix86} +CXXFLAGS="$CXXFLAGS -D_OSP_DEBUG_ -D_OSP_X86_ -D_OSP_EMUL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%else +CXXFLAGS="$CXXFLAGS -D_OSP_DEBUG_ -D_OSP_ARMEL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%endif + +# Call make instruction with smp support +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%post +/sbin/ldconfig +PKG_ID=cwkuromqdr +echo "/usr/etc/package-manager/backend/tpk -i /usr/apps/"${PKG_ID} +/usr/etc/package-manager/backend/tpk -i /usr/apps/${PKG_ID} +cp -f /usr/lib/osp/osp-ui-app-loader /usr/apps/${PKG_ID}/bin/Home +vconftool set -t string db/setting/menuscreen/package_name "cwkuromqdr.Home" -i -u 5000 -f + +%postun +/sbin/ldconfig +PKG_ID=cwkuromqdr +echo "/usr/etc/package-manager/backend/tpk -u "${PKG_ID} +/usr/etc/package-manager/backend/tpk -u ${PKG_ID} + +%files +%defattr(-,root,root,-) +/usr/apps/* diff --git a/res/ara-AE.xml b/res/ara-AE.xml new file mode 100644 index 0000000..6a32ecd --- /dev/null +++ b/res/ara-AE.xml @@ -0,0 +1,14 @@ + + + + نوع الشاشة الرئيسية + تمت + إلغاء + إعدادات الشاشة الرئيسية + Uninstall %ls? + الشاشة الرئيسية الافتراضية + الشاشة الرئيسية + ضبط كصفحة رئيسية + diff --git a/res/aze-AZ.xml b/res/aze-AZ.xml new file mode 100644 index 0000000..e3fcab8 --- /dev/null +++ b/res/aze-AZ.xml @@ -0,0 +1,14 @@ + + + + Başlanğıc ekranı növü + Yerinə yetirildi + Ləğv et + Başlanğıc ekranı parametrləri + Uninstall %ls? + Susmaya görə iş masası + Əsas ekran + Ev kimi qur + diff --git a/res/bul-BG.xml b/res/bul-BG.xml new file mode 100644 index 0000000..360e2bc --- /dev/null +++ b/res/bul-BG.xml @@ -0,0 +1,14 @@ + + + + Тип начален екран + Готово + Отказ + Настройки на началния екран + Uninstall %ls? + Начален екран по подразбиране + Начален екран + Като начало + diff --git a/res/cat-ES.xml b/res/cat-ES.xml new file mode 100644 index 0000000..540ee80 --- /dev/null +++ b/res/cat-ES.xml @@ -0,0 +1,14 @@ + + + + Tipus de pantalla d'inici + Finalitzat + Cancel·lar + Configuració de la pantalla d'inici + Uninstall %ls? + Pantalla d'inici predeterminada + Pantalla d'inici + Def com ini + diff --git a/res/ces-CZ.xml b/res/ces-CZ.xml new file mode 100644 index 0000000..2125f47 --- /dev/null +++ b/res/ces-CZ.xml @@ -0,0 +1,14 @@ + + + + Typ domovské obrazovky + Hotovo + Zrušit + Nastavení domovské obrazovky + Uninstall %ls? + Výchozí domovská obrazovka + Domovská obrazovka + Domovská + diff --git a/res/dan-DK.xml b/res/dan-DK.xml new file mode 100644 index 0000000..9182299 --- /dev/null +++ b/res/dan-DK.xml @@ -0,0 +1,14 @@ + + + + Type af startskærm + Udført + Annullér + Indstillinger for startskærm + Uninstall %ls? + Standardstartskærm + Startskærm + Som start + diff --git a/res/deu-DE.xml b/res/deu-DE.xml new file mode 100644 index 0000000..5863d4e --- /dev/null +++ b/res/deu-DE.xml @@ -0,0 +1,14 @@ + + + + Startanzeige-Typ + OK + Abbrechen + Startseiten-Einstellungen + Uninstall %ls? + Standard-Startbildschirm + Home-Bildschirm + Home-Taste + diff --git a/res/ell-GR.xml b/res/ell-GR.xml new file mode 100644 index 0000000..179624d --- /dev/null +++ b/res/ell-GR.xml @@ -0,0 +1,14 @@ + + + + Τύπος αρχικής οθόνης + Τέλος + Ακύρωση + Ρυθμίσεις αρχικής οθόνης + Uninstall %ls? + Προεπιλεγμένη αρχική οθόνη + Αρχική οθόνη + Ως αρχική + diff --git a/res/eng-GB.xml b/res/eng-GB.xml new file mode 100644 index 0000000..ffc2d04 --- /dev/null +++ b/res/eng-GB.xml @@ -0,0 +1,14 @@ + + + + Home screen type + Done + Cancel + Home screen settings + Uninstall %ls? + Default home screen + Home screen + Set as home + diff --git a/res/eng-PH.xml b/res/eng-PH.xml new file mode 100644 index 0000000..ffc2d04 --- /dev/null +++ b/res/eng-PH.xml @@ -0,0 +1,14 @@ + + + + Home screen type + Done + Cancel + Home screen settings + Uninstall %ls? + Default home screen + Home screen + Set as home + diff --git a/res/eng-US.xml b/res/eng-US.xml new file mode 100644 index 0000000..ffc2d04 --- /dev/null +++ b/res/eng-US.xml @@ -0,0 +1,14 @@ + + + + Home screen type + Done + Cancel + Home screen settings + Uninstall %ls? + Default home screen + Home screen + Set as home + diff --git a/res/est-EE.xml b/res/est-EE.xml new file mode 100644 index 0000000..882fe0d --- /dev/null +++ b/res/est-EE.xml @@ -0,0 +1,14 @@ + + + + Avaekraani tüüp + Valmis + Tühista + Avaekraani seaded + Uninstall %ls? + Vaikimisi avaekraan + Avaleht + Avaekr.-ks + diff --git a/res/eus-ES.xml b/res/eus-ES.xml new file mode 100644 index 0000000..3a0cf92 --- /dev/null +++ b/res/eus-ES.xml @@ -0,0 +1,14 @@ + + + + Pantaila nagusi mota + Amaituta + Ezeztatu + Pantaila nagusiaren ezarpenak + Uninstall %ls? + Lehenetsitako hasierako pantaila + Hasierako pantaila + Ez. nagusi + diff --git a/res/fin-FI.xml b/res/fin-FI.xml new file mode 100644 index 0000000..f867dcb --- /dev/null +++ b/res/fin-FI.xml @@ -0,0 +1,14 @@ + + + + Alkunäytön tyyppi + Tehty + Peruuta + Alkunäytön asetukset + Uninstall %ls? + Oletusalkunäyttö + Alkunäyttö + As. alkun. + diff --git a/res/fra-CA.xml b/res/fra-CA.xml new file mode 100644 index 0000000..e97a035 --- /dev/null +++ b/res/fra-CA.xml @@ -0,0 +1,14 @@ + + + + Type d'écran d'accueil + OK + Annuler + Paramètres de l'écran d'accueil + Uninstall %ls? + Écran d'accueil par défaut + Écran d'accueil + Définir en tant qu'Accueil + diff --git a/res/fra-FR.xml b/res/fra-FR.xml new file mode 100644 index 0000000..06c808e --- /dev/null +++ b/res/fra-FR.xml @@ -0,0 +1,14 @@ + + + + Type d'écran d'accueil + Effectué + Annuler + Paramètres de l'écran d'accueil + Uninstall %ls? + Écran d'accueil par défaut + Écran d'accueil + Accueil + diff --git a/res/gle-IE.xml b/res/gle-IE.xml new file mode 100644 index 0000000..c767e6d --- /dev/null +++ b/res/gle-IE.xml @@ -0,0 +1,14 @@ + + + + Cineál scáileáin bhaile + Déanta + Cuir ar ceal + Socruithe an scáileáin bhaile + Uninstall %ls? + Scáileán baile réamhshocraithe + Scáileán baile + Mar bhaile + diff --git a/res/glg-ES.xml b/res/glg-ES.xml new file mode 100644 index 0000000..5ac12d8 --- /dev/null +++ b/res/glg-ES.xml @@ -0,0 +1,14 @@ + + + + Tipo de pantalla de inicio + Finalizado + Cancelar + Axustes da pantalla de inicio + Uninstall %ls? + Pantalla de inicio predeterminada + Pantalla de inicio + Def inicio + diff --git a/res/hin-IN.xml b/res/hin-IN.xml new file mode 100644 index 0000000..3e94a99 --- /dev/null +++ b/res/hin-IN.xml @@ -0,0 +1,14 @@ + + + + होम स्क्रीन प्रकार + हुआ + रद्द करें + होम स्क्रीन सेटिंग्स + Uninstall %ls? + डिफ़ॉल्ट होम स्क्रीन + होम स्क्रीन + होम जैसे सेट + diff --git a/res/hrv-HR.xml b/res/hrv-HR.xml new file mode 100644 index 0000000..0ef367b --- /dev/null +++ b/res/hrv-HR.xml @@ -0,0 +1,14 @@ + + + + Vrsta početnog zaslona + OK + Prekid + Postavke početnog zaslona + Uninstall %ls? + Zadani početni zaslon + Početni zaslon + Za početnu + diff --git a/res/hun-HU.xml b/res/hun-HU.xml new file mode 100644 index 0000000..23a3834 --- /dev/null +++ b/res/hun-HU.xml @@ -0,0 +1,14 @@ + + + + Kezdőképernyő típusa + Kész + Mégse + Kezdőképernyő beállításai + Uninstall %ls? + Alapértelmezett kezdőképernyő + Kezdőképernyő + Kezdő könyv. + diff --git a/res/hye-AM.xml b/res/hye-AM.xml new file mode 100644 index 0000000..0498d7f --- /dev/null +++ b/res/hye-AM.xml @@ -0,0 +1,14 @@ + + + + Հիմնական էկրանի տեսակը + Կատարված է + Չեղարկել + Հիմնական էկրանի դրվածքներ + Uninstall %ls? + Կանխադրված հիմնական էկրան + Աշխատասեղան + Դնել հմնկն + diff --git a/res/isl-IS.xml b/res/isl-IS.xml new file mode 100644 index 0000000..b8d7c0e --- /dev/null +++ b/res/isl-IS.xml @@ -0,0 +1,14 @@ + + + + Gerð heimaskjás + Lokið + Hætta við + Stillingar heimaskjás + Uninstall %ls? + Sjálfgefinn heimaskjár + Heimaskjár + Heim + diff --git a/res/ita-IT.xml b/res/ita-IT.xml new file mode 100644 index 0000000..4d570d7 --- /dev/null +++ b/res/ita-IT.xml @@ -0,0 +1,14 @@ + + + + Tipo schermata Home + Fatto + Annulla + Impostazioni schermata iniziale + Uninstall %ls? + Schermata Home predefinita + Schermata Home + Come sfondo + diff --git a/res/jpn-JP.xml b/res/jpn-JP.xml new file mode 100644 index 0000000..35e4e67 --- /dev/null +++ b/res/jpn-JP.xml @@ -0,0 +1,14 @@ + + + + ホーム画面タイプ + 完了 + キャンセル + ホーム画面設定 + Uninstall %ls? + 標準ホーム画面 + ホーム画面 + ホームに設定 + diff --git a/res/kat-GE.xml b/res/kat-GE.xml new file mode 100644 index 0000000..4616abe --- /dev/null +++ b/res/kat-GE.xml @@ -0,0 +1,14 @@ + + + + საწყისი ეკრანის ტიპი + შესრულებულია + გაუქმება + საწყისი ეკრანის პარამეტრები + Uninstall %ls? + ნაგულისხმევი საწყისი ეკრანი + საწყისი ეკრანი + საწყ. არჩ. + diff --git a/res/kaz-KZ.xml b/res/kaz-KZ.xml new file mode 100644 index 0000000..8f5e653 --- /dev/null +++ b/res/kaz-KZ.xml @@ -0,0 +1,14 @@ + + + + Бастапқы экран түрі + Аяқталды + Тоқтату + Бастапқы экран параметрлері + Uninstall %ls? + Әдепкі бастапқы экран + Бейнебеттің өзіндік беті + Бас. орнату + diff --git a/res/kor-KR.xml b/res/kor-KR.xml new file mode 100644 index 0000000..1c237f0 --- /dev/null +++ b/res/kor-KR.xml @@ -0,0 +1,14 @@ + + + + 홈 화면 종류 + 완료 + 취소 + 홈 화면 설정 + Uninstall %ls? + 기본 홈 화면 + 홈 화면 + 홈으로 설정 + diff --git a/res/lav-LV.xml b/res/lav-LV.xml new file mode 100644 index 0000000..c33b7b9 --- /dev/null +++ b/res/lav-LV.xml @@ -0,0 +1,14 @@ + + + + Sākums ekrāna veids + Gatavs + Atcelt + Sākuma ekrāna iestatījumi + Uninstall %ls? + Noklusētais sākuma ekrāns + Sākuma ekrāns + Ies. kā sāk. + diff --git a/res/lit-LT.xml b/res/lit-LT.xml new file mode 100644 index 0000000..21e3671 --- /dev/null +++ b/res/lit-LT.xml @@ -0,0 +1,14 @@ + + + + Pradžios ekrano tipas + Atlikta + Atšaukti + Pradžios ekrano nustatymai + Uninstall %ls? + Numatytasis pradžios ekranas + Pradžios ekranas + Nust. prad. + diff --git a/res/mkd-MK.xml b/res/mkd-MK.xml new file mode 100644 index 0000000..d0592aa --- /dev/null +++ b/res/mkd-MK.xml @@ -0,0 +1,14 @@ + + + + Вид почетен екран + Извршено + Откажи + Опции за почетниот екран + Uninstall %ls? + Основен почетен екран + Почетен екран + Пост. почет. + diff --git a/res/nld-NL.xml b/res/nld-NL.xml new file mode 100644 index 0000000..8619c1f --- /dev/null +++ b/res/nld-NL.xml @@ -0,0 +1,14 @@ + + + + Type startscherm + Gereed + Annuleren + Instellingen startscherm + Uninstall %ls? + Standaard startscherm + Startscherm + Startpagina + diff --git a/res/nob-NO.xml b/res/nob-NO.xml new file mode 100644 index 0000000..c68b519 --- /dev/null +++ b/res/nob-NO.xml @@ -0,0 +1,14 @@ + + + + Startskjermtype + Utført + Avbryt + Startskjerminnstillinger + Uninstall %ls? + Standard startskjermbilde + Startskjerm + Angi hjem + diff --git a/res/pol-PL.xml b/res/pol-PL.xml new file mode 100644 index 0000000..36354a4 --- /dev/null +++ b/res/pol-PL.xml @@ -0,0 +1,14 @@ + + + + Typ ekranu startowego + Gotowe + Anuluj + Ustawienia ekranu startowego + Uninstall %ls? + Domyślny ekran startowy + Ekran startowy + Jako domowy + diff --git a/res/por-BR.xml b/res/por-BR.xml new file mode 100644 index 0000000..fd244f9 --- /dev/null +++ b/res/por-BR.xml @@ -0,0 +1,14 @@ + + + + Tipo da tela de início + Concluído + Cancelar + Config. da tela de início + Uninstall %ls? + Tela de início padrão + Tela principal + Definir como inicial + diff --git a/res/por-PT.xml b/res/por-PT.xml new file mode 100644 index 0000000..e00b074 --- /dev/null +++ b/res/por-PT.xml @@ -0,0 +1,14 @@ + + + + Tipo de ecrã principal + Concluído + Cancelar + Definições do ecrã inicial + Uninstall %ls? + Ecrã principal padrão + Ecrã principal + Def. c/ in. + diff --git a/res/ron-RO.xml b/res/ron-RO.xml new file mode 100644 index 0000000..d79c8c3 --- /dev/null +++ b/res/ron-RO.xml @@ -0,0 +1,14 @@ + + + + Tip ecran de pornire + Efectuat + Anulare + Setări ecran de pornire + Uninstall %ls? + Ecran de pornire implicit + Ecran de pornire + Set. acasă + diff --git a/res/rus-RU.xml b/res/rus-RU.xml new file mode 100644 index 0000000..3bbeca9 --- /dev/null +++ b/res/rus-RU.xml @@ -0,0 +1,14 @@ + + + + Тип главного экрана + Готово + Отмена + Параметры главного экрана + Uninstall %ls? + Главный экран по умолчанию + Главный экран + Как главную + diff --git a/res/screen-density-xhigh/BG.png b/res/screen-density-xhigh/BG.png new file mode 100644 index 0000000000000000000000000000000000000000..12a7b34f6a1ea760ecaefd1f5653449da0debf8c GIT binary patch literal 101297 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Menu_Btn_Uninstall.png b/res/screen-density-xhigh/Menu_Btn_Uninstall.png new file mode 100644 index 0000000000000000000000000000000000000000..285c14a0a4ea66fd84f33c1575b676a852409c8c GIT binary patch literal 6124 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 WM<)VQ^V*UC0000c(O literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Menu_Btn_setting_press.png b/res/screen-density-xhigh/Menu_Btn_setting_press.png new file mode 100644 index 0000000000000000000000000000000000000000..38589452b10dbc74e28bf0966d70bb16d0b04902 GIT binary patch literal 3331 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 N002ovPDHLkV1iQ`Ktlik literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_001.png b/res/screen-density-xhigh/Page_indicator_001.png new file mode 100644 index 0000000000000000000000000000000000000000..214c81aa9cddaa31b934406b49af40dfbb9bdda7 GIT binary patch literal 3046 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_002.png b/res/screen-density-xhigh/Page_indicator_002.png new file mode 100644 index 0000000000000000000000000000000000000000..414455313172a16cba8649c8180e86d9f96c8cce GIT binary patch literal 3540 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 AT>t<8 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_010.png b/res/screen-density-xhigh/Page_indicator_010.png new file mode 100644 index 0000000000000000000000000000000000000000..089475413151b848d42abd581e3c546a17174462 GIT binary patch literal 4125 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 bntulXC0y|zLOTtT00000NkvXXu0mjfOG>a{ literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_02.png b/res/screen-density-xhigh/Page_indicator_02.png new file mode 100644 index 0000000000000000000000000000000000000000..98b133473e1277264344d1088b521b71da28ea54 GIT binary patch literal 4093 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 M07*qoM6N<$f+#|4#sB~S literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_05.png b/res/screen-density-xhigh/Page_indicator_05.png new file mode 100644 index 0000000000000000000000000000000000000000..872982e1cca3ffc4a78b2611c5a643baf17bd0a2 GIT binary patch literal 4123 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_07.png b/res/screen-density-xhigh/Page_indicator_07.png new file mode 100644 index 0000000000000000000000000000000000000000..cdf1a99b11c1ca2145323c8bd2263ffc3b3e8767 GIT binary patch literal 3994 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 AF#rGn literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_08.png b/res/screen-density-xhigh/Page_indicator_08.png new file mode 100644 index 0000000000000000000000000000000000000000..f13a8ef71f64dda06aafc815a3df249e90f2b89d GIT binary patch literal 4141 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/Page_indicator_09.png b/res/screen-density-xhigh/Page_indicator_09.png new file mode 100644 index 0000000000000000000000000000000000000000..36c0d32859c300ff754950e6994744e0f3d83cbe GIT binary patch literal 4141 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

D|76m zkl217&F3B~zP_*UOOjA4Y!G4tklG-{aBf8QA~-0?ai>kYJ>>j2@uidqDS79{4a$`Y z7cX3Jb1H;nX?cbFw{P-er8n8Fe2Dd)hbPR5s>mRCi7kT8F|}rsaZ|_Aj_F8zVAJq) zJ9*esHiRpCR%T{o7~AV%_|lfguRbWy%V~rsA(R-UFiN6=5EV#_(0DpT=in*E6>W#* z)GSG`z?3vBx3}>&eLjwJ3DM`Zn3(u%+k^l%JVS& zg^VO|W@d(?)*-cr*ZH9f(|pa$;4xH1>EJj(a!Ix*9Bq*=S2JOqb`sYoY*>F<%2|AS zOZ<5WvF+)IFLCwZ-`Jeu?XW<;;Gun=Fz3_D
+ + + + + + + + + + + + + diff --git a/res/slk-SK.xml b/res/slk-SK.xml new file mode 100644 index 0000000..c2ffa12 --- /dev/null +++ b/res/slk-SK.xml @@ -0,0 +1,14 @@ + + + + Typ domovskej obrazovky + Hotovo + Zrušiť + Nastavenia domovskej obrazovky + Uninstall %ls? + Predvolená domovská obrazovka + Úvodná obrazovka + Nast. domov + diff --git a/res/slv-SI.xml b/res/slv-SI.xml new file mode 100644 index 0000000..61e6bff --- /dev/null +++ b/res/slv-SI.xml @@ -0,0 +1,14 @@ + + + + Vrsta domačega zaslona + Končano + Prekliči + Nastavitve domačega zaslona + Uninstall %ls? + Privzeti domači zaslon + Domači zaslon + Nast. domov + diff --git a/res/spa-ES.xml b/res/spa-ES.xml new file mode 100644 index 0000000..a52c333 --- /dev/null +++ b/res/spa-ES.xml @@ -0,0 +1,14 @@ + + + + Tipo de pantalla de inicio + Guardar + Cancelar + Ajustes de la pantalla de inicio + Uninstall %ls? + Pantalla de inicio predeterminada + Pantalla de inicio + Def inicio + diff --git a/res/spa-MX.xml b/res/spa-MX.xml new file mode 100644 index 0000000..369012a --- /dev/null +++ b/res/spa-MX.xml @@ -0,0 +1,14 @@ + + + + Tipo de pantalla de inicio + Realizado + Cancelar + Configuración de pantalla de inicio + Uninstall %ls? + Pantalla de inicio predeterminada + Pantalla de inicio + Def. inicio + diff --git a/res/srp-RS.xml b/res/srp-RS.xml new file mode 100644 index 0000000..309b868 --- /dev/null +++ b/res/srp-RS.xml @@ -0,0 +1,14 @@ + + + + Tip početnog ekrana + Gotovo + Poništi + Podešavanja početnog ekrana + Uninstall %ls? + Podrazumevani početni ekran + Početni ekran + Kao početni + diff --git a/res/swe-SE.xml b/res/swe-SE.xml new file mode 100644 index 0000000..a1a6f7e --- /dev/null +++ b/res/swe-SE.xml @@ -0,0 +1,14 @@ + + + + Typ för startsida + Klar + Avbryt + Inställningar för hemskärmen + Uninstall %ls? + Standardhemskärm + Hemskärm + Ange st.sid + diff --git a/res/tur-TR.xml b/res/tur-TR.xml new file mode 100644 index 0000000..4754210 --- /dev/null +++ b/res/tur-TR.xml @@ -0,0 +1,14 @@ + + + + Ana ekran tipi + Tamamlandı + İptal + Ana ekran ayarları + Uninstall %ls? + Varsayılan ana ekran + Ana sayfa ekranı + Ana syf yap + diff --git a/res/ukr-UA.xml b/res/ukr-UA.xml new file mode 100644 index 0000000..c364030 --- /dev/null +++ b/res/ukr-UA.xml @@ -0,0 +1,14 @@ + + + + Тип головного екрана + Готово + Скасувати + Установки головного екрана + Uninstall %ls? + Головний екран за замовчанням + Головний екран + Вст.як дом. + diff --git a/res/uzb-UZ.xml b/res/uzb-UZ.xml new file mode 100644 index 0000000..9da8d58 --- /dev/null +++ b/res/uzb-UZ.xml @@ -0,0 +1,14 @@ + + + + Asosiy ekran turi + Bajarildi + Bekor qilish + Asosiy ekran parametrlari + Uninstall %ls? + Birlamchi o‘rnatma bo‘yicha asosiy ekran + Asosiy ekran + Asosiy kabi + diff --git a/res/zho-CN.xml b/res/zho-CN.xml new file mode 100644 index 0000000..f0a57bd --- /dev/null +++ b/res/zho-CN.xml @@ -0,0 +1,14 @@ + + + + 主屏类型 + 完成 + 取消 + 主屏设置 + Uninstall %ls? + 默认主屏 + 主屏 + 设为主页 + diff --git a/res/zho-HK.xml b/res/zho-HK.xml new file mode 100644 index 0000000..353fd4f --- /dev/null +++ b/res/zho-HK.xml @@ -0,0 +1,14 @@ + + + + 主螢幕類型 + 完成 + 取消 + 主螢幕設定 + Uninstall %ls? + 預設主螢幕 + 主螢幕 + 設為首頁 + diff --git a/res/zho-SG.xml b/res/zho-SG.xml new file mode 100644 index 0000000..2e4fa37 --- /dev/null +++ b/res/zho-SG.xml @@ -0,0 +1,14 @@ + + + + 主屏类型 + 已完成 + 取消 + 主屏设置 + Uninstall %ls? + 默认主屏 + 主屏 + 设置为首页 + diff --git a/res/zho-TW.xml b/res/zho-TW.xml new file mode 100644 index 0000000..353fd4f --- /dev/null +++ b/res/zho-TW.xml @@ -0,0 +1,14 @@ + + + + 主螢幕類型 + 完成 + 取消 + 主螢幕設定 + Uninstall %ls? + 預設主螢幕 + 主螢幕 + 設為首頁 + diff --git a/shared/data/nofile.dummy b/shared/data/nofile.dummy new file mode 100644 index 0000000..e69de29 diff --git a/shared/res/screen-density-xhigh/mainmenu.png b/shared/res/screen-density-xhigh/mainmenu.png new file mode 100644 index 0000000000000000000000000000000000000000..b0979b14aa60b43339ecf663ba0dc2db9db42334 GIT binary patch literal 13745 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

IS!eXAF5WR{8w=d_TeJ|>2kFuEp z%D$n~>C)+R=yW=?+ifb93Y*WKv9rCybC)i%va*6wL$q|fA6hEO;^Hzk2>9r;S9v+t z0x9t&_|X^wKlaK=!3DidDQM$IGmpkSw8)N048{AcJu-T--nBbA5u9qHCm?A)e^}=8 zhc$|MgEfLsM}-<~uv((6LoORnp@R?=742=W=bE5{5VS!_Xcj|`I~|VOE)J+vDm;Gl z7-KY7uU(~9s|_V}1SaU3yz}`SOKWR9zI&UGRNmrA?IRp(ffr4V=x4dD6_k}>`CuLV z9DcmUF^TXQvB1CxkDYn>eHdu!qq)`f`210woG%bY67)wF8-WoLEiJ-mtW+4^L;4yW z1Q_2#`yQUx!}J1Fr%Op%ntq4Fqhs=g0!n#2e)O1PvB2fa&rvQ{QUkNcRIRW~)oL8g zF0l9D4L)&gnm_d~j7+pLQn0`=)9o$1d;uxM5dNNJAtyZeuAe#fhEodc#MzgOtC~$D ze60Fq4Le%!8way&*&G$m5EubQA*DrVLD+vLfOaG7rLhQ4A$^4oG|F@8O82^0p?I<0 zA!zMVu2hgx@$kU|W@e^YJ9mykzA)@LP5@=?hsjJM zg-+w!+f%mc480>|HLv!n{Bd`hqOuqp5#IzIRsBQ9Nfj+vQRRMe81p42t5aV`dLEEWsQEv>Ne;0`}nsq^LOm+2T6 zCohR(yu)n@>_>K57R=XU&%J_@i)! zP$~-O!C-FL52vC;iiis9B5Jk}BASjHRjI6ySR+_1hy3)^Q?_p1re_3~uUw(oXb#Jk zHdz3-skxmZtC=D;z_nhl(>j{v@a}hcp|Zg1g;f-mh0ZR8-VuI%F>#NRh)))hJt+aB zlTvKvL(0ZPv|}q~j*uM#UkRr<#HS(+0j|SR^am;li!>r4`cNudK!WP~o26WcJ`O zNDn_6mv$22Py9Ra2opO>%&`wE6aCzL*0URv`SAZ|rnycXUmC)wxm!f}d}*wk!xPP` z8a~Tc4BQW4!3e>W(0r=2%O_fI(7E*%<>nmcFPx`PC}53AJX|fF;T01rRT)67=stYk zXL)s%d$(?K>CtO6S3f}U;3B%Oem6Mq!L7gu;!JM<50?(MUw11jsb*F z%+Jj;J2Q(EBAe?+eb33nA3ziPZs^#tlqu+V#;gUK?mmv)-0a*e)oRt10mUdtDa*JE z0lw$E6mT?zTgmt|5|fygaxw%^WOlGH>GKJynuwXyXxjNCBb-6_kvL!y7mt5HWyTlH zct(qql2SAyI{Q%~DI1b9j)^&@Dc}BNl|%A5k4%z)G53_ReJA<$lZZd=$4hXNN!`#X z9$Gf`IlE(UL}MQT!sz%+#^LKv3jxd^*rYNc?=q-5iSUy~T6>u_*9@T5$3s-wEA>lRTEOO%A7k z0A@C8?T7sB{SAvVJsvExddC&0Z=2LYU%1e>UGCi(fN z@a@kqMZb>=N_I((LrIT#L6b(bOqdjsZ8*mmSIb1THW2`oLDb2Fe~-TX83;dE03n3( zq6tybL={RA3*!69^2nnTRzzEeDeYr5MGSHcB1%)Zt@~9(pAk`>NQ`{0f8Kr%t*|0C zJUn%L>>2N(pB}+R@5eq*e@^Z2sog_#*RVM59uP$G@AxxpZ1Qm`@pGn5b*i7JNkw_P zySuyBuYcS2dR=2o8jd!aS{`eV?YrRolf0dAK~<)|e-__9!&sj&mopA9cG@2ygzR)W bd;fm`MUDJsOv@Tf00000NkvXXu0mjfc@}m4 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing00.png b/res/screen-density-xhigh/progressing00.png new file mode 100644 index 0000000000000000000000000000000000000000..3f96c5af16b9d609e38fb6dcc3bccabb7f0c3505 GIT binary patch literal 3301 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing00_big.png b/res/screen-density-xhigh/progressing00_big.png new file mode 100644 index 0000000000000000000000000000000000000000..43fc7d0e44fa09321f5aa0a917dca5e73c7e1b63 GIT binary patch literal 6091 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 F{{j*@{L%mb literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing01.png b/res/screen-density-xhigh/progressing01.png new file mode 100644 index 0000000000000000000000000000000000000000..a2fd21ee71049b7e40517d4fd54ec989de5ad875 GIT binary patch literal 3526 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 J@z^5hzW}02@Sp$y literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing02.png b/res/screen-density-xhigh/progressing02.png new file mode 100644 index 0000000000000000000000000000000000000000..32a69c3b64b5f2199e674842872c2ebe4bc2c284 GIT binary patch literal 3270 zcmb7Hc{o)2AD*#gZL<`*jFBxd3uBD255vgFPC`xQFoRjl48~H52xUpOxDrK4L{~*A zsvDz5WvOh@szvra;y1e0y?@;2KF{ww&pF@i^S>HP~_NpbKDq#oJbN209lb42LK3xMhXI40TMYXtPL;)frP85?%o`4 zqN7OwgQibfv(e|$m;y8iWNN`>k^({i4&(q3M5UWS$8R-3Ayl#%)C)y~6PY-GLbZ=( z0dCPw?g7yu0T?pW!W?4CH4zZd01gSlrG?VjCR{V|?N z48bv200gBE*9(9f!68NneT0D_8jaowLBbJm7#s;hAoUPv69c3P91i*MKm}?na-fN; z4gQCgU}XlSa5zj87%Va}Qa{o_pTP=(Aut%s8V3@oC$P|CN6|SXt{$DO{*%E5UA5re}zC}x>AEE9QH4AI{Qbm1ZjhDNlX|*9}Z)Ew^@ttCyGe? zZv>6@%bLw`1^#yaU-{YYQA_~l3a}aBtN=k31J(Z__1{8khCgC3A(B`jfS`(aQYahv zen2Fe>=rmrrISK!7y;olfX*Ssbj&J+fR!KN^n5S$wd;zgyC8IkO@LJOD$f!Y8p zY6L*WvlukU_nezh|3%%{2yQ5d6oE8A;cVduK?5Od@Mr`MVSuuN<1oh1A6WALoi3Qb z6WCgh{iEl8ZV4KBZTjm52^PQZAV3$Cj3u~XT_eL>5J>zA!N$s++xNvMBy^jX{28pl z($rXA%4knT|8~~zNtx!Qnb2-+H97lAS4Gh&VV8~a);Zd)XCaga857AHT?kSamo2SW zI-4(+Jhi5%iRWkr zJ^%RISXAtXZG{qQ*&|UGABLOfg7m?@LiHjw<+$R{;DAt1smn|Bj8#wRt6Q#0PO0+V zZe$l|j3vZ+sLahn8116Xz2DHfT`qnesN}qgxrJ8=_l&MfwuauVD#~1Up@88VyX495 z*V-0RRGN&cpJm%~ItnO$t?8QOpGLw;lU}7a4@=eG7VUH%h6@GPuh73LHtzwoO=3iP z8zGuLN9KGB#cH~bhOzBD48zo=4{6*fi?vAkSeu*i`m^J}rUhQzqvNg#6Sgdo);7&S ztt}DryS(nAVh1MU(r>;VR8Y8lD=oc*48vuzk7H5`7FW=Ny4R%dHl*#kFyy6tV|;OE zsc@6hvu=1@e(h$oDOBmyzyJqdPiGcaP2h zb~?e1E$T_Ap8ofPBk%Ax)bFVz>BP#dySC}ZA=hZ{XF|zoaHf2S$F@fbfll&9h{ID< z!sF30ke&ZxFDSnK_|pT2H^~@3*BMy79dxZCa(&t!^$#~|{5J{>%F1ElJ_P;tln>VH zoUkjugwB+2E+(nP*ELr5fv(+qRbe_Q?{vmW1SD2}y6mY_-|~8LWl;Hm{RRDRb1N67 z53U|+gb%Pm(<*bzo1dg8WPS51I%cr?tsl+*v-jI`%6J}goG)@Kzd_!6^@;P*!waq`Nx3vyaZIpVJ+12-XlodHXT4PJC$(c#aG$vCUG*$kT&IW( zLG93>G-0~@!`x9qpzNqUXhnpX{gSMun_%1EXMA1^8pCr9JawsE;VcwA@Ral79BsBR z!lJp`vM}eQn<>eNOlwZ)QR(2r--Ppd0-zeoo$FL)DR{ zJPmsOouogp$(Pk#fTjaucf+t%6a!EDz%o-xM$^*3KC4#}#!V> zGdG1#pNSj8X&}E0H>cJdjGt$hW{i71OvsLVzHYCPNHb1`_fZRr=}Np;H8WMULFT!( zNm3XUH>P}lX>Umz!PY3Y*zu$9{ao1G%rdv=Vzy?Fp-;K$luzeT!)Fzt-6apn{)TE+ z#t%_So$l?6mtE4zWizm|N^tjebs@Odh7;q#x+|Cba=hOrbWn;dIx#=&z>nsj0j#Np@&ZkLd7L zs^$ydl6u;Tl92CGJK77!-gg)iv42A@>~j*h{z9FWPaAJG;=^%L?ba5F^Er)YCHk5D znwjrW;QA?p-7T5dUkWFRY8_F(L)QNE+X!)?J!FNmTW1B6Mtlnm*I3$k?ut3}!;-%; zI0LIw=H%A3zO|*y+D=})~zDZ%*Oz~r0YpY$MCsR3(solt(xOm&v-@_ z_Vo9AU*DOzk+Q)dg{#Padh+%#uU0GR_W_F7b7ZaE3-Yv%=Je1dA@{UhTCD0P;OuT6 zXYUqKZ11WgxxMIM*%6J!mM)nA{y>sUOO0A-#`Dg>Pah}ui8P$_KmK8pR-rgZn|i+Y zt@-DxfRk!1Y$Y)Aq0)%*v{Tn86kBezh5oyq)}JJ8-r!zE6*{&8JNxlXuk(tdAcf=Kyo5sJ z_RA|&6RrT>!~)3ZJF$JSMju{m5a8+F80Yzwma{%ELE4<-w=8(kne*CiA`Kac;L)Y@#kNc_lnZ znBW`j26=g6i>u~TEm3-%HI0U^ocA_4K4~d|2zBv^1Mtq9C(`fQO2MP2TZMz+KIn!} zX&0=8U&|K}p=V6$()x~UkF2VlTbo0lJc{3&=-V-qf9ayhN1HPEzG~`wIkDZqcHxWF z#tLA*UZCvzfR|0CGMiQL_UNOuIfO@C(4~g^s|%#(+f3Lhh9r=$%IVIf>8jOBgA00H zmC}!N^9l;9uRe8vHh54+YD*u_%_4JG`k4~1HaBY=M*X%byB}oz)>lur?l@}g&w^m< KWK(UuKmLC(Et#YM literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing02_big.png b/res/screen-density-xhigh/progressing02_big.png new file mode 100644 index 0000000000000000000000000000000000000000..094ca9d23418b7cb03e2a16b92e7bdc2d194cf66 GIT binary patch literal 5982 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing03.png b/res/screen-density-xhigh/progressing03.png new file mode 100644 index 0000000000000000000000000000000000000000..46bf26ec29363fa856cfb74d177bdb8fdc1bb5e5 GIT binary patch literal 3485 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 P+7A-}?}EEw@1OV|+k^L+ literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing03_big.png b/res/screen-density-xhigh/progressing03_big.png new file mode 100644 index 0000000000000000000000000000000000000000..8d2a57e719f980198009bda701f0190580697d5f GIT binary patch literal 6439 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 ItHGlF1M@)I2LJ#7 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing05.png b/res/screen-density-xhigh/progressing05.png new file mode 100644 index 0000000000000000000000000000000000000000..b7e60d9f9b872603a83b3329a7365623ecf4c740 GIT binary patch literal 3479 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 KM=0Iz8~s1fc<-42 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing05_big.png b/res/screen-density-xhigh/progressing05_big.png new file mode 100644 index 0000000000000000000000000000000000000000..d76826bde7c308d2bcc6d0ed5d7e3bcc2cd87840 GIT binary patch literal 6520 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing06.png b/res/screen-density-xhigh/progressing06.png new file mode 100644 index 0000000000000000000000000000000000000000..665a1d574ba4b29c77e788955d428c45d35bd37c GIT binary patch literal 3289 zcmb7Hc{o)2AD(c9lASbY8ZB2b%P|XMlrdv6i8R(IOfv@)votgIB@u;0i))Q?Em5jl zC{kogQQcICEJ@iZp)Bzm-Rj;y?sK2#cb?~*@Ai4$_p^QfII*@iJLTop$w43xd734K zE*_1RUm0of_fm|Bj(E@%SvZUAc%GsFh5&?+SiFNEjK*Pjfpn0;3Of7{BtjsP#cX?L zk+bz~0+Yu7i3SYNc!D87K%rpYAGlae!15%} zDb(*;;*}}fTO{HWkjQ|507QTxf+z4oqK%D>mpK5yKx|SRuJC)Z#A!nYGWbX|0)-TOvssSs2g=&| zzY!eHPivuw4*u=@zw!(1gZLnl4hngG0;af%p1S{#`fs6S!|yQ=tQi6yP+UbS!&eA? zJFvDU>=8T9<}!RKJft0Hh?}#!fnur`tTqrwd{{7IfHcEMxCe)8`Pv^awY82aGZlD9&})# z4j1kAy}a_6T5uI~?M%S=JTLLd#FUNPni$av&lbM!3iMYtX-jr^x66Hey8OXFXw^h0 zZ)aa-$klgNGyC7R!K*DI;vpI=l(`L(I0@%3ceJHOh=?9m%(Rhd(wxn(rn#s?i*u;DS>R2 zRWY;jamStBh{m>^^bU{dEH`dVDFQ8vJpuE`t(ns3^9?kXRku*ksjrdv@aPQ6ID>t+ z)R*R18%W%fZNd$?B!8mPV)_`76`KFS!?8VBcF>X0#Ea?{e3k0Nb5B363t?;v)00u4 zZBdrE&l$^iPpioClvm{m{A|OTu3gmbEcM7- z#xCi%c{2s(DCmd9kwES=>N&N2Z!eo>dzUMDZYoyg^-xP%);Xm=!NciqauVLyrzOWZ zYb-5R8;30vD;fHGQf5le|5~J5h~_rT7E}?^g95zUPb4gANSH+Y(Ntgh(HOF#yS{m} zV1w2#ogIp*Tl#(@F}9%HBj|aUg55>=i1qE`Jh{&X_o+8ju5`R+>w1UOH4No!Z2=%G zr^aB_4IWkzh@y>~VNCwdf1wK&!Zwrrykxs7bg(Qb*E?M$ zca#IhRXwhGTc=e%;9HngIqZ6ex7YQzE_;z}q$Wsc*t~R>@G-G=42ruM+@DhtXFA>D zsC#(o>0Ykqr;?j?-~k!K^anWS*j$IYmXh-c6VJ?j-25Uh@6^(d*sV2t7CTd?k>gJ| zqsq0-a_o$ZLtKi-mM*0fBn57{o|Pig3vcK*G07kV+Z=dow#UC7K@|IE<49+Mas03Q=-3NfHt$!;xza724dzo|a$l9qsiJ(c{8B>USh0-rOlHGTj zMV&kDUdn>@s&e0FNnPg{HIEb;Cd|uKc2p$UXb0`l4bIQbn0;Cug<~inrM~Q|47S8% z4J#=22B)6>nvom4^13mWoe=p*;2BpIeS}ot1+}7-K2d5^^L)RyHQ)KO%%I)NvNe|_ zPP`a%%xq1%GCN+q_)62p@(kI7mC~r-bCnAe%xJ57P9esR(cMBw)9R9@JQc{QLg3NpCu15F#-X-_IylIKdknAC7fj4Z@_ z$$e26TYX>M{h98T3A66oDO(r%`um|z!=-Lnd*n;1swyuv%yVMhkEMa38Lq)=DeFG& zU46u@-RPAFDT5&q$ z%s}?sBiotgrcTCjUA~!;Co8M=OZcs~u)-%47Qg9w?ws2v#8cr>BTM#ES{!q{DJcSh*U Wvm%Ph2IrT5HfR<$l&j_*k^ci~Zlw_b literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing06_big.png b/res/screen-density-xhigh/progressing06_big.png new file mode 100644 index 0000000000000000000000000000000000000000..738bdf97a1ba350d84974dbc9498212198512f04 GIT binary patch literal 5931 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 literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing07.png b/res/screen-density-xhigh/progressing07.png new file mode 100644 index 0000000000000000000000000000000000000000..d56600ec75ae3d7b02562f218cedefe6892db942 GIT binary patch literal 3474 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 LI%6tq0uufQ(MSTf literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/progressing07_big.png b/res/screen-density-xhigh/progressing07_big.png new file mode 100644 index 0000000000000000000000000000000000000000..ff3d34dab34424a40e0f4cea4185e43cee8650fa GIT binary patch literal 6537 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 + + + + + 720 +

D|76m zkl217&F3B~zP_*UOOjA4Y!G4tklG-{aBf8QA~-0?ai>kYJ>>j2@uidqDS79{4a$`Y z7cX3Jb1H;nX?cbFw{P-er8n8Fe2Dd)hbPR5s>mRCi7kT8F|}rsaZ|_Aj_F8zVAJq) zJ9*esHiRpCR%T{o7~AV%_|lfguRbWy%V~rsA(R-UFiN6=5EV#_(0DpT=in*E6>W#* z)GSG`z?3vBx3}>&eLjwJ3DM`Zn3(u%+k^l%JVS& zg^VO|W@d(?)*-cr*ZH9f(|pa$;4xH1>EJj(a!Ix*9Bq*=S2JOqb`sYoY*>F<%2|AS zOZ<5WvF+)IFLCwZ-`Jeu?XW<;;Gun=Fz3_D

IS!eXAF5WR{8w=d_TeJ|>2kFuEp z%D$n~>C)+R=yW=?+ifb93Y*WKv9rCybC)i%va*6wL$q|fA6hEO;^Hzk2>9r;S9v+t z0x9t&_|X^wKlaK=!3DidDQM$IGmpkSw8)N048{AcJu-T--nBbA5u9qHCm?A)e^}=8 zhc$|MgEfLsM}-<~uv((6LoORnp@R?=742=W=bE5{5VS!_Xcj|`I~|VOE)J+vDm;Gl z7-KY7uU(~9s|_V}1SaU3yz}`SOKWR9zI&UGRNmrA?IRp(ffr4V=x4dD6_k}>`CuLV z9DcmUF^TXQvB1CxkDYn>eHdu!qq)`f`210woG%bY67)wF8-WoLEiJ-mtW+4^L;4yW z1Q_2#`yQUx!}J1Fr%Op%ntq4Fqhs=g0!n#2e)O1PvB2fa&rvQ{QUkNcRIRW~)oL8g zF0l9D4L)&gnm_d~j7+pLQn0`=)9o$1d;uxM5dNNJAtyZeuAe#fhEodc#MzgOtC~$D ze60Fq4Le%!8way&*&G$m5EubQA*DrVLD+vLfOaG7rLhQ4A$^4oG|F@8O82^0p?I<0 zA!zMVu2hgx@$kU|W@e^YJ9mykzA)@LP5@=?hsjJM zg-+w!+f%mc480>|HLv!n{Bd`hqOuqp5#IzIRsBQ9Nfj+vQRRMe81p42t5aV`dLEEWsQEv>Ne;0`}nsq^LOm+2T6 zCohR(yu)n@>_>K57R=XU&%J_@i)! zP$~-O!C-FL52vC;iiis9B5Jk}BASjHRjI6ySR+_1hy3)^Q?_p1re_3~uUw(oXb#Jk zHdz3-skxmZtC=D;z_nhl(>j{v@a}hcp|Zg1g;f-mh0ZR8-VuI%F>#NRh)))hJt+aB zlTvKvL(0ZPv|}q~j*uM#UkRr<#HS(+0j|SR^am;li!>r4`cNudK!WP~o26WcJ`O zNDn_6mv$22Py9Ra2opO>%&`wE6aCzL*0URv`SAZ|rnycXUmC)wxm!f}d}*wk!xPP` z8a~Tc4BQW4!3e>W(0r=2%O_fI(7E*%<>nmcFPx`PC}53AJX|fF;T01rRT)67=stYk zXL)s%d$(?K>CtO6S3f}U;3B%Oem6Mq!L7gu;!JM<50?(MUw11jsb*F z%+Jj;J2Q(EBAe?+eb33nA3ziPZs^#tlqu+V#;gUK?mmv)-0a*e)oRt10mUdtDa*JE z0lw$E6mT?zTgmt|5|fygaxw%^WOlGH>GKJynuwXyXxjNCBb-6_kvL!y7mt5HWyTlH zct(qql2SAyI{Q%~DI1b9j)^&@Dc}BNl|%A5k4%z)G53_ReJA<$lZZd=$4hXNN!`#X z9$Gf`IlE(UL}MQT!sz%+#^LKv3jxd^*rYNc?=q-5iSUy~T6>u_*9@T5$3s-wEA>lRTEOO%A7k z0A@C8?T7sB{SAvVJsvExddC&0Z=2LYU%1e>UGCi(fN z@a@kqMZb>=N_I((LrIT#L6b(bOqdjsZ8*mmSIb1THW2`oLDb2Fe~-TX83;dE03n3( zq6tybL={RA3*!69^2nnTRzzEeDeYr5MGSHcB1%)Zt@~9(pAk`>NQ`{0f8Kr%t*|0C zJUn%L>>2N(pB}+R@5eq*e@^Z2sog_#*RVM59uP$G@AxxpZ1Qm`@pGn5b*i7JNkw_P zySuyBuYcS2dR=2o8jd!aS{`eV?YrRolf0dAK~<)|e-__9!&sj&mopA9cG@2ygzR)W bd;fm`MUDJsOv@Tf00000NkvXXu0mjfc@}m4 literal 0 HcmV?d00001 diff --git a/shared/trusted/nofile.dummy b/shared/trusted/nofile.dummy new file mode 100644 index 0000000..e69de29 diff --git a/src/HmApplicationUtils.cpp b/src/HmApplicationUtils.cpp new file mode 100644 index 0000000..dc0480a --- /dev/null +++ b/src/HmApplicationUtils.cpp @@ -0,0 +1,315 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either exprs or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmApplicationUtils.cpp + * @brief Keeps the implementations for Utility functions, + * Implementations of the various Utility function which may be used throughout the application + */ + +#include +#include +#include +#include +#include +#include "HmApplicationUtils.h" +#include "HmTypes.h" + +using namespace Tizen::App; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Graphics; +using namespace Tizen::Media; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; + +Bitmap* +ApplicationUtils::GetApplicationIconBitmapN(const String& imagePath, const String& appCaption, bool isResourceBitmap) +{ + result r = E_SUCCESS; + Canvas* pCanvas = null; + Bitmap* pBitmap = null; + Bitmap* pAppIconBitmap = null; + EnrichedText appEnrichedCaption; + EnrichedText appEnrichedShadowCaption; + TryReturn(!imagePath.IsEmpty(), null, "Invalid Parameter"); + + if (isResourceBitmap) + { + pBitmap = GetResourceBitmapN(imagePath); + } + + if (pBitmap == null) + { + pBitmap = GetBitmapN(imagePath); + // creates bitmap for the icon if is default icon path + if (pBitmap == null) + { + pBitmap = GetResourceBitmapN(IDB_DEFAULT_APP_ICON); + } + } + + TryCatch(pBitmap != null, , "Failed to create bitmap"); + + if (pBitmap->GetHeight() != APP_ICON_IMAGE_SIZE || pBitmap->GetWidth() != APP_ICON_IMAGE_SIZE) + { + pBitmap->Scale(Dimension(APP_ICON_IMAGE_SIZE, APP_ICON_IMAGE_SIZE)); + } + // get a Canvas instance + pCanvas = new (std::nothrow) Canvas(); + TryCatch(pCanvas != null, , "Failed to allocate for Canvas"); + + r = pCanvas->Construct(Rectangle(0, 0, W_APPLICATION_ICON, H_APPLICATION_ICON)); + TryCatch(r == E_SUCCESS, , "pCanvas->Construct failed with error %s", GetErrorMessage(r)); + pCanvas->SetBackgroundColor(Color(0, 0, 0, 0)); + pCanvas->Clear(); + + r = pCanvas->DrawBitmap(Point((W_APPLICATION_ICON - pBitmap->GetWidth()) / 2, Y_APP_ICON_IMAGE_START) /*, APP_ICON_IMAGE_SIZE, APP_ICON_IMAGE_SIZE)*/, *pBitmap); + TryCatch(r == E_SUCCESS, , "pCanvas->DrawBitmap failed with error %s", GetErrorMessage(r)); + + if (!appCaption.IsEmpty()) + { + Font font; + String fontToUse; + TextElement captionElement; + + IList* pFontsList = Font::GetSystemFontListN(); + + if (pFontsList != null) + { + IEnumerator* pEnum = pFontsList->GetEnumeratorN(); + + if (pEnum != null) + { + while (pEnum->MoveNext() == E_SUCCESS) + { + String* pFontName = static_cast(pEnum->GetCurrent()); + + if (pFontName && pFontName->Contains(L"HelveticaNeue")) + { + fontToUse = *pFontName; + break; + } + } + + delete pEnum; + pEnum = null; + } + + pFontsList->RemoveAll(true); + delete pFontsList; + pFontsList = null; + } + + if (fontToUse.IsEmpty()) + { + r = font.Construct(FONT_STYLE_PLAIN, FONT_SIZE_APP_CAPTION); + TryCatch(r == E_SUCCESS, , "font.Construct failed with error = %s", GetErrorMessage(r)); + } + else + { + AppLogDebug("FontTest :: Calling with font.Construct(name) "); + r = font.Construct(fontToUse, FONT_STYLE_PLAIN, FONT_SIZE_APP_CAPTION); + TryCatch(r == E_SUCCESS, , "font.Construct failed with error = %s", GetErrorMessage(r)); + } + + // app name text + r = captionElement.Construct(appCaption); + TryCatch(r == E_SUCCESS, , "captionElement.Construct failed with error = %s", GetErrorMessage(r)); + captionElement.SetTextColor(COLOR_APP_ICON_CAPTION); + captionElement.SetFont(font); + captionElement.SetOutlineColor(COLOR_APP_CAPTION_SHADOW1); + appEnrichedCaption.Construct(Dimension(W_APPLICATION_ICON, H_APP_CAPTION_TEXT)); + appEnrichedCaption.SetHorizontalAlignment(TEXT_ALIGNMENT_CENTER); + appEnrichedCaption.SetVerticalAlignment(TEXT_ALIGNMENT_MIDDLE); + appEnrichedCaption.SetTextWrapStyle(TEXT_WRAP_NONE); + appEnrichedCaption.SetTextAbbreviationEnabled(true); + appEnrichedCaption.Add(captionElement); + + // app name shadow text + TextElement shadowCaptionElement; + r = shadowCaptionElement.Construct(appCaption); + TryCatch(r == E_SUCCESS, , "shadowCaptionElement.Construct failed with error = %s", GetErrorMessage(r)); + shadowCaptionElement.SetTextColor(COLOR_APP_CAPTION_SHADOW2); + shadowCaptionElement.SetFont(font); + shadowCaptionElement.SetOutlineColor(COLOR_APP_CAPTION_SHADOW2); + appEnrichedShadowCaption.Construct(Dimension(W_APPLICATION_ICON, H_APP_CAPTION_TEXT)); + appEnrichedShadowCaption.SetHorizontalAlignment(TEXT_ALIGNMENT_CENTER); + appEnrichedShadowCaption.SetVerticalAlignment(TEXT_ALIGNMENT_MIDDLE); + appEnrichedShadowCaption.SetTextWrapStyle(TEXT_WRAP_NONE); + appEnrichedShadowCaption.SetTextAbbreviationEnabled(true); + appEnrichedShadowCaption.Add(shadowCaptionElement); + + pCanvas->DrawText(Point(0, Y_APP_ICON_IMAGE_START + APP_ICON_IMAGE_SIZE + 2), appEnrichedShadowCaption); + pCanvas->DrawText(Point(0, Y_APP_ICON_IMAGE_START + APP_ICON_IMAGE_SIZE), appEnrichedCaption); + } + + pAppIconBitmap = new (std::nothrow) Bitmap(); + TryCatch(pAppIconBitmap != null, , "Failed to allocate for Bitmap"); + r = pAppIconBitmap->Construct(*pCanvas, Rectangle(0, 0, W_APPLICATION_ICON, H_APPLICATION_ICON)); + TryCatch(r == E_SUCCESS, , "pCanvas->Construct failed with error %s", GetErrorMessage(r)); + + if (pBitmap != null) + { + delete pBitmap; + pBitmap = null; + } + + if (pCanvas != null) + { + delete pCanvas; + pCanvas = null; + } + + return pAppIconBitmap; + +CATCH: + + if (pBitmap != null) + { + delete pBitmap; + pBitmap = null; + } + + if (pCanvas != null) + { + delete pCanvas; + pCanvas = null; + } + + if (pAppIconBitmap != null) + { + delete pAppIconBitmap; + pAppIconBitmap = null; + } + + return null; +} + +Bitmap* +ApplicationUtils::GetBitmapN(const String& imageAbsolutePath) +{ + result r = E_SUCCESS; + Bitmap* pBitmap = null; + Image* pImage = new (std::nothrow) Image(); + + String fullname; + fullname.Append(imageAbsolutePath); + + if (pImage != null) + { + r = pImage->Construct(); + // goes to CATCH to release memory and return null if failed to construct Image + TryCatch(r == E_SUCCESS, , "Image Construct Failed = (%s)\n", GetErrorMessage(r)); + // creates bitmap for the specified path of the image which is of jpeg format. + if (fullname.EndsWith(L"jpg") || fullname.EndsWith(L"JPG") || fullname.EndsWith(L"jpeg") || fullname.EndsWith(L"JPEG")) + { + pBitmap = pImage->DecodeN(fullname, BITMAP_PIXEL_FORMAT_RGB565); + } + // creates bitmap for the specified path of the image which is of bmp format. + else if (fullname.EndsWith(L"bmp") || fullname.EndsWith(L"BMP")) + { + pBitmap = pImage->DecodeN(fullname, BITMAP_PIXEL_FORMAT_RGB565); + } + // creates bitmap for the specified path of the image which is of png and wbmp formats. + else if (fullname.EndsWith(L"png") || fullname.EndsWith(L"PNG") || fullname.EndsWith(L"wbmp") || fullname.EndsWith(L"WBMP")) + { + pBitmap = pImage->DecodeN(fullname, BITMAP_PIXEL_FORMAT_ARGB8888); + } + // creates bitmap for the specified path of the image which is of gif format. + else if (fullname.EndsWith(L"gif") || fullname.EndsWith(L"GIF")) + { + pBitmap = pImage->DecodeN(fullname, BITMAP_PIXEL_FORMAT_RGB565); + } + + // goes to CATCH to release memory and return null if failed to construct bitmap + TryCatch(pBitmap != null, , "not found image path or not enough memory %ls error = %s", fullname.GetPointer() + , GetErrorMessage(GetLastResult())); + + delete pImage; + return pBitmap; + } + +CATCH: + + if (pImage != null) + { + delete pImage; + } + + return null; +} + +Bitmap* +ApplicationUtils::GetResourceBitmapN(const String& imageName) +{ + //sanity test + TryReturn(!imageName.IsEmpty(), null, "Invalid parameter"); + + AppResource* pAppResource = UiApp::GetInstance()->GetAppResource(); + Bitmap* pBitmap = null; + + // creates bitmap for the specified image name from the application resource. + pBitmap = pAppResource->GetBitmapN(imageName, BITMAP_PIXEL_FORMAT_ARGB8888); + + TryReturn(pBitmap != null, pBitmap, "failed to create bitmap error = %s", GetErrorMessage(GetLastResult())); + + return pBitmap; +} + +result +ApplicationUtils::GetStringResource(const String& stringId, String& retString) +{ + result r = E_INVALID_ARG; + + if (!stringId.IsEmpty()) + { + AppResource* pAppResource = UiApp::GetInstance()->GetAppResource(); + r = pAppResource->GetString(stringId, retString); + } + + return r; +} + +//Shows delete confirmation message box +int +ApplicationUtils::ShowDeletePopup(String& applicationName) +{ + MessageBox messsageBox; + String message; + String messageTitle; + String displayMessage; + int modalResult = 0; + //get the resource string + GetStringResource(L"IDS_IDLE_POP_UNINSTALL_PS_Q", message); + //format the message by including the application name + displayMessage.Format(256, message.GetPointer(), applicationName.GetPointer()); + messsageBox.Construct(messageTitle, displayMessage, MSGBOX_STYLE_YESNO); + //Show message box and wait for user response + messsageBox.ShowAndWait(modalResult); + + return modalResult; +} + +ApplicationUtils::ApplicationUtils(void) +{ + // No implementation required +} + +ApplicationUtils::~ApplicationUtils(void) +{ + // No implementation required +} diff --git a/src/HmCustomIconListProvider.cpp b/src/HmCustomIconListProvider.cpp new file mode 100644 index 0000000..7138b70 --- /dev/null +++ b/src/HmCustomIconListProvider.cpp @@ -0,0 +1,228 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmCustomIconListProvider.cpp = false; + * @brief This is the implementation for the IconListItemProviderCustom class + * This class contains the functions which are required managing the IconListView's items + */ + +#include "HmApplicationUtils.h" +#include "HmCustomIconListProvider.h" +#include "HmCustomPageControl.h" +#include "HmHomeItemInfo.h" +#include "HmTypes.h" + +using namespace Tizen::App; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Graphics; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; + +CustomIconListProvider::CustomIconListProvider(int index) + : __editMode(false) + , __isProjectedItemInvalid(false) + , __index(index) + , __iconsPerPage(0) + , __currentIndex(-1) + , __pPageItemProvider(null) + , __pMovementItem(null) + , __pOverayBitmap(null) +{ + // No implementation required +} + +CustomIconListProvider::~CustomIconListProvider(void) +{ + if (__pOverayBitmap != null) + { + delete __pOverayBitmap; + __pOverayBitmap = null; + } +} + +bool +CustomIconListProvider::GetEditMode(void) const +{ + return __editMode; +} + +IconListViewItem* +CustomIconListProvider::GetMovingItem(void) const +{ + return __pMovementItem; +} + +int +CustomIconListProvider::GetMovingItemIndex() const +{ + return __currentIndex; +} + +IPageControlItemProvider* +CustomIconListProvider::GetPageControlItemProvider(void) +{ + return __pPageItemProvider; +} + +void +CustomIconListProvider::SetEditMode(bool editMode) +{ + // sets the edit mode + __editMode = editMode; + return; +} + +void +CustomIconListProvider::SetIndex(int index) +{ + // sets the index of the provider + __index = index; + return; +} + +void +CustomIconListProvider::SetMaxCountOfIcons(int iconCount) +{ + // sets the maximum number of icons in the page. + __iconsPerPage = iconCount; + return; +} + +void +CustomIconListProvider::SetMovingItem(Tizen::Ui::Controls::IconListViewItem* pMovedItem) +{ + __pMovementItem = pMovedItem; +} + +void +CustomIconListProvider::SetMovingItemIndex(int movedIndex) +{ + __currentIndex = movedIndex; +} + +void +CustomIconListProvider::SetPageControlItemProvider(IPageControlItemProvider* pItemProvider) +{ + __pPageItemProvider = pItemProvider; +} + +void +CustomIconListProvider::SetProjectedItemInvalid(bool isInvalid) +{ + __isProjectedItemInvalid = isInvalid; +} + +IconListViewItem* +CustomIconListProvider::CreateItem(int index) +{ + IconListViewItem* pItem = null; + HomeItemInfo* pItemInfo = null; + + pItemInfo = __pPageItemProvider->GetItem(__index, index); + // if application icon + if (pItemInfo != null) + { + + if (__pMovementItem != null && __currentIndex == index && !__isProjectedItemInvalid) + { + pItem = __pMovementItem; + } + else + { + Bitmap* pItemBitmap = null; + String appName = static_cast(pItemInfo)->GetAppName(); + String iconPath = pItemInfo->GetIconPath(); + + if (!iconPath.IsEmpty()) + { + // gets the application icon if exists + pItemBitmap = pItemInfo->GetApplicationIcon(); + // creates the icon if application icon doesn't exist. + if (pItemBitmap == null) + { + pItemBitmap = ApplicationUtils::GetApplicationIconBitmapN(iconPath, appName); + pItemInfo->SetApplicationIcon(pItemBitmap); + } + } + // constructs the item for the IconListView + if (pItemBitmap != null) + { + pItem = new (std::nothrow) IconListViewItem(); // + pItem->Construct(*pItemBitmap); + } + } + + + if (__editMode) + { + bool showDeleteButton = true; + + if (pItemInfo != null) + { + showDeleteButton = pItemInfo->IsUnistallable(); + } + + if (showDeleteButton) + { + if (__pOverayBitmap == null) + { + __pOverayBitmap = ApplicationUtils::GetResourceBitmapN(IDB_CLOSE_ICON); + } + + if (__pOverayBitmap != null) + { + // adds overlay bitmap to IconListView items if in edit mode. + if (pItem != null) + { + pItem->SetOverlayBitmap(IDA_OVERLAYBITMAP_CLOSE, __pOverayBitmap, ALIGNMENT_RIGHT, ALIGNMENT_TOP); + } + } + } + } + } + return pItem; +} + +bool +CustomIconListProvider::DeleteItem(int index, IconListViewItem* pItem) +{ + if (pItem != null) + { + if (__pMovementItem != null && __pMovementItem->GetHashCode() == pItem->GetHashCode()) + { + return true; + } + + delete pItem; + pItem = null; + return true; + } + + return false; +} + +int +CustomIconListProvider::GetItemCount(void) +{ + if (__pPageItemProvider != null) + { + return __pPageItemProvider->GetItemCount(__index); + } + + return 0; +} diff --git a/src/HmCustomPageControl.cpp b/src/HmCustomPageControl.cpp new file mode 100644 index 0000000..c9877ce --- /dev/null +++ b/src/HmCustomPageControl.cpp @@ -0,0 +1,947 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmCustomPageControl.h + * @brief Keeps implementation of the HmCustomPageControl + * Implements the CustomPageControl class, it overrides default scrolling functionality of IconListView + */ + +#include +#include +#include "HmApplicationUtils.h" +#include "HmCustomIconListProvider.h" +#include "HmCustomPageControl.h" +#include "HmCustomPageMarker.h" +#include "HmHomeItemInfo.h" +#include "HmICustomPageControlEventListener.h" +#include "HmTypes.h" + +using namespace Tizen::App; +using namespace Tizen::App::Package; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Graphics; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Animations; +using namespace Tizen::Ui::Controls; + +CustomPageControl::CustomPageControl(void) + : __hasPageMoved(false) + , __isDragging(false) + , __isInEditMode(false) + , __needAnimation(false) + , __pDraggingAppInfo(null) + , __pEventListener(null) + , __currentIndex(-1) + , __currentPageNumber(0) + , __iconsCount(MAX_ICONS_PER_PAGE) + , __pageNumber(0) + , __pageToBeDeleted(-1) + , __pageWidth(W_DEFAULT_PAGE) + , __startIndex(-1) + , __sweepTraveled(0) + , __totalPages(1) + , __pPageItemProvider(null) + , __pIconListProviders(null) + , __pIconLists(null) + , __pPageMovementTimer(null) + , __pMovingItemBitmap(null) + , __animationEndPoint(0, 0) + , __animationStartPoint(0, 0) + , __dragStartPosition(0, 0) + , __iconListCurrentPos(0, 0) + , __iconListRestPosition(0, 0) + , __touchStartPoint(0, 0) + , __pMovementItem(null) + , __pMovementLabel(null) + , __pGetureDetector(null) +{ + //no implementation required +} + +CustomPageControl::~CustomPageControl(void) +{ + if (__pPageMovementTimer != null) + { + __pPageMovementTimer->Cancel(); + delete __pPageMovementTimer; + __pPageMovementTimer = null; + } + + if (__pIconLists != null) + { + __pIconLists->RemoveAll(false); //the controls will be deleted using removeControl calls by framework + delete __pIconLists; + } + + if (__pIconListProviders != null) + { + __pIconListProviders->RemoveAll(true); + delete __pIconListProviders; + } + + if (__pGetureDetector != null) + { + __pGetureDetector->RemoveLongPressGestureEventListener(*this); + delete __pGetureDetector; + } +} + +result +CustomPageControl::Construct(const Rectangle& controlRect, int noOfPages, + int pageWidth) +{ + result r = E_SUCCESS; + int width = noOfPages* pageWidth; + int xPos = X_PAGE_POSITION; + int yPos = 0; + String iconListViewNameBase; + + r = Panel::Construct(controlRect); + TryCatch(r == E_SUCCESS, , "Panel::Construct(controlRect) failed with error = %s", GetErrorMessage(r)); + __totalPages = noOfPages; + __pageWidth = pageWidth; + __currentPageNumber = 1; + __pIconLists = new (std::nothrow) ArrayList(); + __pIconLists->Construct(); + + __pGetureDetector = new (std::nothrow) TouchLongPressGestureDetector(); + __pGetureDetector->Construct(); + __pGetureDetector->SetDuration(LONG_TOUCH_GESTURE_DURATION); + __pGetureDetector->AddLongPressGestureEventListener(*this); + + __pIconListProviders = new (std::nothrow) ArrayList(); + __pIconListProviders->Construct(); + SetSize(Dimension(width, controlRect.height)); + + for (int pageNumber = 1; pageNumber <= __totalPages; pageNumber++) + { + IconListView* pIconListView = new (std::nothrow) IconListView(); + + if (pIconListView != null) + { + CustomIconListProvider* pProvider = null; + r = pIconListView->Construct(Rectangle(xPos, yPos, __pageWidth /*- (2 * POSITION_OFFSET)*/, (controlRect.height)), Dimension(W_APPLICATION_ICON, H_APPLICATION_ICON), + ICON_LIST_VIEW_STYLE_NORMAL, ICON_LIST_VIEW_SCROLL_DIRECTION_VERTICAL); + + TryCatch(r == E_SUCCESS, delete pIconListView; + pIconListView = null, "pIconListView->Construct pageNumber %d error %s", pageNumber, GetErrorMessage(r)); + + String iconListName(iconListViewNameBase); + iconListName.Append(pageNumber); + pIconListView->SetName(iconListName); + pIconListView->SetMargin(MARGIN_TYPE_LEFT, 0); + pIconListView->SetMargin(MARGIN_TYPE_RIGHT, 0); + pIconListView->SetTextOfEmptyList(L""); + pIconListView->SetItemTextSize(FONT_SIZE_APP_CAPTION); + pIconListView->SetTouchAnimationEnabled(false); + pIconListView->AddTouchEventListener(*this); + pIconListView->AddGestureDetector(*__pGetureDetector); + pIconListView->SetItemSpacing(GAP_ICON_HORIZONTAL, GAP_ICON_VERTICAL); + pIconListView->AddIconListViewItemEventListener(*this); + + pProvider = new (std::nothrow) CustomIconListProvider(pageNumber); + + if (pProvider != null) + { + pProvider->SetMaxCountOfIcons(__iconsCount); + __pIconListProviders->Add(pProvider); + + pIconListView->SetItemProvider(*pProvider); + AddControl(*pIconListView); + __pIconLists->Add(pIconListView); + xPos += __pageWidth; + } + else + { + if (pIconListView != null) + { + delete pIconListView; + pIconListView = null; + } + } + } + } + + __pMovementLabel = new (std::nothrow) Label(); + r = __pMovementLabel->Construct(Rectangle(0, 0, W_APPLICATION_ICON, H_APPLICATION_ICON), L""); + TryCatch(r == E_SUCCESS, , "__pLabel->Construct failed with error %s", GetErrorMessage(r)); + __pMovementLabel->SetShowState(false); + + r = AddControl(*__pMovementLabel); + TryCatch(r == E_SUCCESS, , "AddControl(*__pLabel)failed with error %s", GetErrorMessage(r)); + + return r; + +CATCH: + + if (__pIconLists != null) + { + delete __pIconLists; + __pIconLists = null; + } + + if (__pIconListProviders != null) + { + __pIconListProviders->RemoveAll(true); + delete __pIconListProviders; + __pIconListProviders = null; + } + + return r; +} + +result +CustomPageControl::AddPage(void) +{ + if (__totalPages > MAX_PAGE_COUNT) + { + return E_FAILURE; + } + + result r = E_SUCCESS; + Rectangle currentBounds = GetBounds(); + IconListView* pIconListView = null; + String iconListName; + CustomIconListProvider* pProviderTemp = null; + int xPos = currentBounds.width + X_PAGE_POSITION; + + __totalPages++; + pIconListView = new (std::nothrow) IconListView(); + r = pIconListView->Construct(Rectangle(xPos, 0, __pageWidth - (2 * X_PAGE_POSITION), (currentBounds.height)), + Dimension(W_APPLICATION_ICON, H_APPLICATION_ICON), ICON_LIST_VIEW_STYLE_NORMAL, ICON_LIST_VIEW_SCROLL_DIRECTION_VERTICAL); + TryCatch(r == E_SUCCESS, , "pIconListView->Construct failed with error %s", GetErrorMessage(r)); + iconListName.Append(__totalPages); + pIconListView->SetName(iconListName); + // adds IconListViewItemEventListener for the IconListView + pIconListView->AddTouchEventListener(*this); + pIconListView->AddIconListViewItemEventListener(*this); + pIconListView->SetMargin(MARGIN_TYPE_LEFT, 0); + pIconListView->SetMargin(MARGIN_TYPE_RIGHT, 0); + pIconListView->SetTouchAnimationEnabled(false); + // Sets the vertical alignment of the text of IconListView item + pIconListView->AddGestureDetector(*__pGetureDetector); + pIconListView->SetItemSpacing(GAP_ICON_HORIZONTAL, GAP_ICON_VERTICAL); + + pProviderTemp = new (std::nothrow) CustomIconListProvider(__totalPages); + pProviderTemp->SetPageControlItemProvider(static_cast(__pIconListProviders->GetAt(0))->GetPageControlItemProvider()); + pProviderTemp->SetEditMode(__isInEditMode); + r = __pIconListProviders->Add(pProviderTemp); + TryCatch(r == E_SUCCESS, delete pProviderTemp; + pProviderTemp = null, "__pIconListProviders->Add(pProviderTemp) %s", GetErrorMessage(r)); + // sets provider for the IconListView + pIconListView->SetItemProvider(*pProviderTemp); + + __pIconLists->Add(pIconListView); + TryCatch(r == E_SUCCESS, , "__pIconLists->Add(pIconListView) %s", GetErrorMessage(r)); + + currentBounds.width += __pageWidth; + SetBounds(currentBounds); + r = AddControl(*pIconListView); + TryCatch(r == E_SUCCESS, , "AddControl(*pIconListView) %s", GetErrorMessage(r)); + SetControlAlwaysOnTop(*__pMovementLabel, true); + + if (__pEventListener != null) + { + __pEventListener->OnPageAdded(__totalPages); + } + + return r; + +CATCH: + + if (pIconListView != null) + { + delete pIconListView; + pIconListView = null; + } + + return r; +} + +int +CustomPageControl::GetCurrentSelectedPage(void) +{ + return __currentPageNumber; +} + +ArrayList* +CustomPageControl::GetIconLists(void) +{ + return __pIconLists; +} + +const int +CustomPageControl::GetPageCount(void) +{ + return __totalPages; +} + +void +CustomPageControl::MarkPageToDelete(int pageNumber) +{ + if (pageNumber > 1 && pageNumber <= __totalPages) + { + SetPageSelected(pageNumber - 1); + + __pageToBeDeleted = pageNumber; + + if (__pPageMovementTimer == null) + { + __pPageMovementTimer = new (std::nothrow) Timer(); + __pPageMovementTimer->Construct(*this); + } + + __pPageMovementTimer->Cancel(); + __pPageMovementTimer->Start(MOVEMENT_UPDATE_DURATION); + } + return; +} + +void +CustomPageControl::MovePage(void) +{ + __pEventListener->OnPageSwept(__pageNumber); + SetPageSelected(__pageNumber); + __hasPageMoved = true; + __isDragging = true; + + if (__pPageMovementTimer == null) + { + __pPageMovementTimer = new Timer(); + __pPageMovementTimer->Construct(*this); + } + + __pPageMovementTimer->Start(MOVEMENT_UPDATE_DURATION); + return; +} + +void +CustomPageControl::SetMaxNumberOfIcons(int iconsCount) +{ + __iconsCount = iconsCount; +} + +void +CustomPageControl::SetPageControlEventListener(ICustomPageControlEventListener* pListener) +{ + __pEventListener = pListener; + return; +} + +void +CustomPageControl::SetPageControlItemProvider(IPageControlItemProvider* pItemProvider) +{ + __pPageItemProvider = pItemProvider; + + for (int providerCount = 0; providerCount < __pIconListProviders->GetCount(); providerCount++) + { + CustomIconListProvider* pProvider = static_cast(__pIconListProviders->GetAt(providerCount)); + + if (pProvider != null) + { + pProvider->SetPageControlItemProvider(pItemProvider); + } + } +} + +void +CustomPageControl::SetPageSelected(int pageNumber) +{ + if (__currentPageNumber == pageNumber || pageNumber < 1 || pageNumber > __totalPages) + { + return; + } + else + { + Point newPosition = GetPosition(); + + if (pageNumber > __totalPages && pageNumber <= MAX_PAGE_COUNT + 1) + { + // pageNumber = __totalPages; + AddPage(); + } + + __animationStartPoint = GetPosition(); + newPosition.x = (pageNumber - 1) * (-__pageWidth); + __animationEndPoint = newPosition; + __currentPageNumber = pageNumber; + __needAnimation = true; + + if (__pPageMovementTimer == null) + { + __pPageMovementTimer = new Timer(); + __pPageMovementTimer->Construct(*this); + } + + __pPageMovementTimer->Start(SCROLL_ANIMATION_DURATION); + + } + return; + +} + +void +CustomPageControl::ToggleEditMode(void) +{ + if (!__isInEditMode) + { + IEnumerator* pIconListViewEnum = __pIconLists->GetEnumeratorN(); + IEnumerator* pIconListProviderEnum = __pIconListProviders->GetEnumeratorN(); + + while (!IsFailed(pIconListViewEnum->MoveNext()) && !IsFailed(pIconListProviderEnum->MoveNext())) + { + IconListView* pIconListView = static_cast(pIconListViewEnum->GetCurrent()); + + if (pIconListView != null) + { + CustomIconListProvider* pProvider = static_cast + (pIconListProviderEnum->GetCurrent()); + if (pProvider != null) + { + pProvider->SetEditMode(true); + // updates the edit mode value + __isInEditMode = true; + // updates list to add overlay bitmap to provide uninstall option. + pIconListView->UpdateList(); + } + } + } + delete pIconListViewEnum; + delete pIconListProviderEnum; + + } + else + { + IEnumerator* pIconListViewEnum = __pIconLists->GetEnumeratorN(); + IEnumerator* pIconListProviderEnum = __pIconListProviders->GetEnumeratorN(); + + while (!IsFailed(pIconListViewEnum->MoveNext()) && !IsFailed(pIconListProviderEnum->MoveNext())) + { + IconListView* pIconListView = static_cast(pIconListViewEnum->GetCurrent()); + + if (pIconListView != null) + { + CustomIconListProvider* pProvider = static_cast + (pIconListProviderEnum->GetCurrent()); + + if (pProvider != null) + { + pProvider->SetEditMode(false); + // updates the edit mode value + __isInEditMode = false; + __isDragging = false; + // updates list to remove overlay bitmap. + pIconListView->UpdateList(); + __pMovementLabel->SetShowState(false); + } + } + } + delete pIconListViewEnum; + delete pIconListProviderEnum; + } +} + +void +CustomPageControl::OnIconListViewItemStateChanged(Controls::IconListView& iconListView, int index, Controls::IconListViewItemStatus status) +{ + int pageNumber = 0; + Integer::Parse(iconListView.GetName(), pageNumber); + HomeItemInfo* pItemInfo = static_cast(__pPageItemProvider->GetItem(pageNumber, index)); + // launches the application if its an application icon and if in edit mode + if (pItemInfo != null) + { + if (!__isInEditMode) + { + String appId = static_cast(pItemInfo)->GetAppId(); + AppManager* pAppManager = AppManager::GetInstance(); + + if (pAppManager != null) + { + pAppManager->LaunchApplication(appId); + } + } + } + return; +} + +void +CustomPageControl::OnIconListViewOverlayBitmapSelected(Controls::IconListView& iconListView, int index, int overlayBitmapId) +{ + int pageNumber = 1; + HomeItemInfo* pItemInfo = null; + Integer::Parse(iconListView.GetName(), pageNumber); + + pItemInfo = __pPageItemProvider->GetItem(pageNumber, index); + + if (pItemInfo != null) + { + PackageManager* pPackageManager = null; + String appId = pItemInfo->GetAppId(); + String applicationName = pItemInfo->GetAppName(); + if (ApplicationUtils::ShowDeletePopup(applicationName) != MSGBOX_RESULT_YES) + { + return; + } + + pPackageManager = PackageManager::GetInstance(); + + if (pPackageManager != null) + { + // uninstalls the application + String packageId = pPackageManager->GetPackageIdByAppId(appId); + result r = pPackageManager->UninstallPackage(packageId, null); + + if (IsFailed(r)) + { + AppLogException("UninstallPackage returned %s", GetErrorMessage(r)); + } + else + { + __pEventListener->OnAppUninstallRequested(pItemInfo); + } + } + } +} + +void +CustomPageControl::OnTimerExpired(Timer& timer) +{ + if (__pPageMovementTimer != null && timer.Equals(*__pPageMovementTimer)) + { + if (__needAnimation) + { + result r = E_SUCCESS; + ControlAnimator* pAnimatorLeft = GetControlAnimator(); + + if (pAnimatorLeft->GetStatus() == ANIMATOR_STATUS_PLAYING) + { + r = pAnimatorLeft->StopAllAnimations(); + } + + r = pAnimatorLeft->SetPosition(__animationEndPoint); + + if (IsFailed(r)) + { + AppLogDebug("ScrollCheck::pAnimatorLeft->SetPosition failed %s", GetErrorMessage(r)); + SetPosition(__animationEndPoint); + Invalidate(false); + } + + __needAnimation = false; + return; + + } + + if (__pageToBeDeleted == -1) + { + __hasPageMoved = false; + } + else + { + RemovePage(__pageToBeDeleted); + __pageToBeDeleted = -1; + } + } + + + return; +} + +void +CustomPageControl::OnTouchMoved(const Control& source, const Point& currentPosition, const TouchEventInfo& touchInfo) +{ + result r = E_SUCCESS; + + if (!__isDragging /*&& !__isInEditMode*/) + { + int panelWidth = GetWidth() - __pageWidth; + int x = 0, y = 0; + GetPosition(x, y); + x = x + (currentPosition.x - __touchStartPoint.x); + + if (x <= 0 && x >= panelWidth - (2* panelWidth)) + { + SetPosition(Point(x, y)); + } + } + else if (__isDragging /* && __isInEditMode*/) + { + + int startPageNumber; + int xMaxBounds; + int xMinBounds; + + r = Integer::Parse(source.GetName(), startPageNumber); + __pageNumber = GetCurrentSelectedPage(); + + xMinBounds = source.GetBounds().x + (source.GetBounds().width) * (__pageNumber - startPageNumber) + X_PAGE_OFFSET; + xMaxBounds = source.GetBounds().x + (source.GetBounds().width) * (__pageNumber - startPageNumber + 1) - X_PAGE_OFFSET; + IconListView* pIconListView = static_cast(__pIconLists->GetAt(__pageNumber - 1)); + CustomIconListProvider* pProvider = static_cast(__pIconListProviders->GetAt(__pageNumber - 1)); + + if ((source.GetBounds().x + currentPosition.x) >= xMaxBounds && !__hasPageMoved) + { + if (!IsFailed(r)) + { + int totalPages = GetPageCount(); + + if (__pageNumber < totalPages) + { + __pageNumber++; + CustomIconListProvider* pProviderTemp = static_cast(__pIconListProviders->GetAt(__pageNumber - 1)); + pProvider->SetProjectedItemInvalid(true); + pProviderTemp->SetMovingItem(__pMovementItem); + pProviderTemp->SetMovingItemIndex(-1); + MovePage(); + } + } + } + else if ((source.GetBounds().x + currentPosition.x) <= xMinBounds && !__hasPageMoved) + { + if (!IsFailed(r)) + { + if (__pageNumber > 1) + { + CustomIconListProvider* pProviderTemp = null; + __pageNumber--; + pProviderTemp = static_cast(__pIconListProviders->GetAt(__pageNumber - 1)); + pProvider->SetProjectedItemInvalid(true); + pProviderTemp->SetMovingItem(__pMovementItem); + pProviderTemp->SetMovingItemIndex(-1); + MovePage(); + } + } + } + else + { + if (pIconListView != null) + { + Point tempCurrentPoint(0, 0); + int pageNumber = 0; + int x = 0; + int y = 0; + int oldIndex = __currentIndex; + // gets the current page number + Integer::Parse(source.GetName(), pageNumber); + x = currentPosition.x - W_DEFAULT_PAGE * (__pageNumber - pageNumber); + y = currentPosition.y; + tempCurrentPoint.SetPosition(x, y); + __currentIndex = pIconListView->GetItemIndexFromPosition(tempCurrentPoint); + + if (__currentIndex != -1) + { + if (__pDraggingAppInfo == null) + { + __pDraggingAppInfo = static_cast(__pPageItemProvider->GetItem(__pageNumber, __startIndex)); + } + + if (__pMovementItem == null) + { + Bitmap* pIconBitmap = __pDraggingAppInfo->GetApplicationIcon(); + __pMovingItemBitmap = new Bitmap(); + __pMovingItemBitmap->Construct(*pIconBitmap, Rectangle(0, 0, pIconBitmap->GetWidth(), pIconBitmap->GetHeight())); + __pMovingItemBitmap->SetAlphaConstant(MOVING_ICON_OPACITY); + __pMovementItem = new (std::nothrow) IconListViewItem(); + __pMovementItem->Construct(*__pMovingItemBitmap); + pProvider->SetMovingItem(__pMovementItem); + pProvider->SetMovingItemIndex(__currentIndex); + pIconListView->RefreshList(__startIndex, LIST_REFRESH_TYPE_ITEM_MODIFY); + } + else if (__currentIndex != oldIndex) + { + HomeItemInfo* pItemInfo = __pPageItemProvider->GetItem(__pageNumber, __currentIndex); + + if (pItemInfo != null) + { + __pPageItemProvider->RearrangeItems(__pDraggingAppInfo, __pageNumber, __currentIndex); + pProvider->SetMovingItemIndex(__currentIndex); + pIconListView->UpdateList(); + } + } + } + } + } + + __pMovementLabel->SetShowState(true); + __pMovementLabel->SetPosition(source.GetBounds().x + currentPosition.x - (W_APPLICATION_ICON / 2), source.GetBounds().y + currentPosition.y - (H_APPLICATION_ICON / 2)); + + } + return; +} + +void +CustomPageControl::OnTouchPressed(const Control& source, const Point& currentPosition, const TouchEventInfo& touchInfo) +{ + const IconListView* pSourceControl = static_cast(&source); + __dragStartPosition = currentPosition; + + if (pSourceControl != null) + { + __touchStartPoint.x = currentPosition.x; + __iconListCurrentPos = GetPosition(); + __iconListRestPosition = GetPosition(); + __sweepTraveled = 0; + } + + return; +} + +void +CustomPageControl::OnTouchReleased(const Control& source, const Point& currentPosition, const TouchEventInfo& touchInfo) +{ + result r = E_SUCCESS; + + if (/*!__isInEditMode &&*/ !__isDragging) + { + Point tempPoint = GetPosition(); + int panelWidth = GetWidth() - __pageWidth; + //int threshold = (GetParent()->GetWidth() / 2); + int threshold = (__pageWidth / 2); + int diff = 0; + + if (tempPoint.x < __iconListCurrentPos.x) + { + diff = (__iconListCurrentPos.x - tempPoint.x); + } + else + { + diff = (tempPoint.x - __iconListCurrentPos.x); + } + + if (diff >= threshold /*|| touchInfo.IsFlicked()*/) + { + // need to scroll horizontally + + if (tempPoint.x > __iconListCurrentPos.x && __currentPageNumber > 1) + { + __currentPageNumber--; + + } + else + { + if (__currentPageNumber < __totalPages) + { + __currentPageNumber++; + } + } + + __iconListCurrentPos.x = (__currentPageNumber - 1) * (__pageWidth) - (2 * (__currentPageNumber - 1) * (__pageWidth)); + + if (__iconListCurrentPos.x <= 0 && __iconListCurrentPos.x >= panelWidth - (2* panelWidth)) + { + ControlAnimator* pAnimatorLeft = GetControlAnimator(); + + if (pAnimatorLeft != null) + { + __needAnimation = true; + __animationStartPoint = GetPosition(); + __animationEndPoint = __iconListCurrentPos; + if (__pPageMovementTimer == null) + { + __pPageMovementTimer = new Timer(); + __pPageMovementTimer->Construct(*this); + } + + __pPageMovementTimer->Start(SCROLL_ANIMATION_DURATION); + } + else + { + r = E_FAILURE; + } + + if (__pEventListener != null) + { + __pEventListener->OnPageSwept(__currentPageNumber); + } + } + } + else + { + if (__iconListRestPosition.x <= 0 && __iconListRestPosition.x >= panelWidth - (2* panelWidth)) + { + int position = (__currentPageNumber - 1) * (__pageWidth); + __iconListRestPosition.x = position - (2* position); + __needAnimation = true; + __animationStartPoint = GetPosition(); + __animationEndPoint = __iconListRestPosition; + + if (__pPageMovementTimer == null) + { + __pPageMovementTimer = new Timer(); + __pPageMovementTimer->Construct(*this); + } + + __pPageMovementTimer->Start(SCROLL_ANIMATION_DURATION); + } + } + } + else + { + if (__isDragging && __startIndex > -1) + { + int pageNumber = 0; + // gets the current page number + Integer::Parse(source.GetName(), pageNumber); + // gets the IconListView of the current page + IconListView* pIconListView = static_cast(__pIconLists->GetAt(__pageNumber - 1)); + + if (pIconListView != null) + { + // gets the index for the current position + for (int providerCount = 0; providerCount < __pIconListProviders->GetCount(); providerCount++) + { + + CustomIconListProvider* pProvider = static_cast(__pIconListProviders->GetAt(providerCount)); + + if (pProvider->GetMovingItemIndex() != -1 || pProvider->GetMovingItem() != null) + { + IconListView* pIconListView = static_cast(__pIconLists->GetAt(__pageNumber - 1)); + pProvider->SetProjectedItemInvalid(true); + pIconListView->RefreshList(pProvider->GetMovingItemIndex(), LIST_REFRESH_TYPE_ITEM_MODIFY); + pProvider->SetMovingItemIndex(-1); + pProvider->SetMovingItem(null); + pProvider->SetProjectedItemInvalid(false); + } + } + + if (__pMovementItem != null) + { + delete __pMovementItem; + __pMovementItem = null; + + if (__pMovingItemBitmap) + { + delete __pMovingItemBitmap; + __pMovingItemBitmap = null; + } + } + + if (__startIndex != __currentIndex && __currentIndex != -1) + { + pIconListView->UpdateList(); + } + + __currentIndex = -1; + __pMovementLabel->SetShowState(false); + __isDragging = false; + __hasPageMoved = false; + __startIndex = -1; + __pDraggingAppInfo = null; + return; + } + } + + __pMovementLabel->SetShowState(false); + __isDragging = false; + __hasPageMoved = false; + } + __sweepTraveled = 0; + return; +} + +void +CustomPageControl::OnLongPressGestureDetected(TouchLongPressGestureDetector& gestureDetector) +{ + if (gestureDetector.Equals(*__pGetureDetector)) + { + if (__isInEditMode && !__isDragging) + { + IconListView* pIconListView = null; + // gets the IconListView of the current page + pIconListView = static_cast(__pIconLists->GetAt(__currentPageNumber - 1)); + + if (pIconListView != null) + { + HomeItemInfo* pItemInfo = null; + // gets the index of the item that is being dragged + __startIndex = pIconListView->GetItemIndexFromPosition(__dragStartPosition); + pItemInfo = __pPageItemProvider->GetItem(__currentPageNumber, __startIndex); + //gets the info of the item that is being dragged + if (pItemInfo != null) + { + __pDraggingAppInfo = pItemInfo; + + if (__pDraggingAppInfo != null) + { + if (__startIndex > -1) + { + Bitmap* pLabelBitmap = null; + __pageNumber = GetCurrentSelectedPage(); + pLabelBitmap = __pDraggingAppInfo->GetApplicationIcon(); + + if (pLabelBitmap == null) + { + String appIconPath = __pDraggingAppInfo->GetIconPath(); + pLabelBitmap = ApplicationUtils::GetBitmapN(appIconPath); + } + + __pMovementLabel->SetBackgroundBitmap(*pLabelBitmap); + __pMovementLabel->Invalidate(false); + __pMovementLabel->SetShowState(true); + __pMovementLabel->SetPosition(pIconListView->GetBounds().x + __dragStartPosition.x - (W_APPLICATION_ICON / 2), pIconListView->GetBounds().y + __dragStartPosition.y - (H_APPLICATION_ICON / 2)); + __isDragging = true; + } + } + } + + } + } + } + + return; +} + +result +CustomPageControl::RemovePage(int pageNumber) +{ + result r = E_SUCCESS; + IconListView* pControl = static_cast(__pIconLists->GetAt(pageNumber - 1)); + + if (pControl != null) + { + RemoveControl(*pControl); + __pIconLists->Remove(*pControl, false); + __pIconListProviders->RemoveAt(pageNumber - 1, true); + + for (int controlCount = pageNumber + 1; controlCount <= __totalPages; controlCount++) + { + String controlName; + IconListView* pControl = null; + controlName.Append(pageNumber); + pControl = static_cast(GetControl(controlName)); + + if (pControl != null) + { + Point curPos = pControl->GetPosition(); + curPos.x -= __pageWidth; + SetPosition(curPos); + } + } + + __totalPages--; + + if (__pEventListener != null) + { + __pEventListener->OnPageRemoved(pageNumber); + } + + Invalidate(true); + } + return r; +} diff --git a/src/HmCustomPageMarker.cpp b/src/HmCustomPageMarker.cpp new file mode 100644 index 0000000..8fd0ead --- /dev/null +++ b/src/HmCustomPageMarker.cpp @@ -0,0 +1,314 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file CustomPageMarker.cpp + * @brief Keeps implementation of the CustomPageMarker + * implements CustomPageMarker class, which contains the top bubble's bar which indicates the page number + */ + + +#include +#include +#include +#include +#include "HmApplicationUtils.h" +#include "HmCustomPageMarker.h" +#include "HmTypes.h" + +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Graphics; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Animations; +using namespace Tizen::Ui::Controls; + +CustomPageMarker::CustomPageMarker(void) + : __pMarkerListener(null) + , __bubbleCount(1) + , __selectedBubble(0) + , __pBubbleLabels(null) + , __pBubbleBitmaps(null) +{ + //No implementation needed +} + +CustomPageMarker::~CustomPageMarker(void) +{ + if (__pBubbleLabels != null) + { + __pBubbleLabels->RemoveAll(false); //the controls will be deleted using removeControl calls by framework + delete __pBubbleLabels; + } + + if (__pBubbleBitmaps != null) + { + __pBubbleBitmaps->RemoveAll(true); + delete __pBubbleBitmaps; + } +} + +result +CustomPageMarker::Construct(const Rectangle& controlRect, int bubbleCount) +{ + result r = E_SUCCESS; + int xPos = 0; + int yPos = Y_MARKER_POSITION; + int width = 0; + int xFactor = 0; + Bitmap* pUnselectedBitmap = null; + Bitmap* pSelectedBitmap = null; + __bubbleCount = bubbleCount; + + r = Panel::Construct(controlRect, GROUP_STYLE_NONE); + TryCatch(r == E_SUCCESS, , "Panel::Construct failed with error %s", GetErrorMessage(r)); + + __pBubbleLabels = new (std::nothrow) ArrayList(); + r = __pBubbleLabels->Construct(); + TryCatch(r == E_SUCCESS, , "__pLabels->Construct(); failed with error %s", GetErrorMessage(r)); + + __pBubbleBitmaps = new (std::nothrow) ArrayList(); + r = __pBubbleBitmaps->Construct(); + pUnselectedBitmap = ApplicationUtils::GetResourceBitmapN(IDB_BUBBLE_TOP); + + if (pUnselectedBitmap != null) + { + __pBubbleBitmaps->Add(pUnselectedBitmap); + } + + for (int bubbleCountTemp = 1; bubbleCountTemp <= __bubbleCount; bubbleCountTemp++) + { + String bubbleName(IDB_SELECTED_BUBBLE_TOP); + bubbleName.Append(bubbleCountTemp); + bubbleName.Append(BITMAP_EXTENSION); + pSelectedBitmap = ApplicationUtils::GetResourceBitmapN(bubbleName); + + if (pSelectedBitmap != null) + { + __pBubbleBitmaps->Add(pSelectedBitmap); + } + } + + width = (controlRect.width); + xFactor = width - ((W_MARKER_LABEL * __bubbleCount) + (X_MARKER_LABEL_OFFSET * (__bubbleCount - 1))); + + xPos = xFactor / 2; + + for (int bubbleCount = 1; bubbleCount <= __bubbleCount; bubbleCount++) + { + Label* pLabel = new (std::nothrow) Label(); + String labelName; + labelName.Append(bubbleCount); + + if (pLabel != null) + { + Rectangle labelRect(xPos, yPos, W_MARKER_LABEL, H_MARKER_LABEL); + pLabel->Construct(labelRect, L""); + pLabel->SetBackgroundBitmap(*static_cast(__pBubbleBitmaps->GetAt(0))); + pLabel->SetTextColor(Color::GetColor(COLOR_ID_BLACK)); + pLabel->SetTextHorizontalAlignment(ALIGNMENT_CENTER); + pLabel->SetTextVerticalAlignment(ALIGNMENT_MIDDLE); + pLabel->SetName(labelName); + pLabel->AddTouchEventListener(*this); + AddControl(*pLabel); + __pBubbleLabels->Add(pLabel); + xPos += W_MARKER_LABEL + X_MARKER_LABEL_OFFSET; + } + } + + return r; + +CATCH: + + if (__pBubbleLabels != null) + { + delete __pBubbleLabels; + __pBubbleLabels = null; + } + return r; +} + +result +CustomPageMarker::AddBubble(void) +{ + result r = E_SUCCESS; + Rectangle controlRect = GetBounds(); + int width = 0; + int xFactor = 0; + int xPos = 0; + int yPos = Y_MARKER_POSITION; + Label* pLabel = null; + String labelName; + __bubbleCount++; + + width = (controlRect.width); + xFactor = width - ((W_MARKER_LABEL * __bubbleCount) + (X_MARKER_LABEL_OFFSET * (__bubbleCount - 1))); + + xPos = xFactor / 2; + + for (int bubbleCount = 1; bubbleCount < __bubbleCount; bubbleCount++) + { + String labelName; + labelName.Append(bubbleCount); + Label* pLabel = static_cast(GetControl(labelName)); + + if (pLabel != null) + { + Rectangle labelRect(xPos, yPos, W_MARKER_LABEL, H_MARKER_LABEL); + pLabel->SetBounds(labelRect); + xPos += (X_MARKER_LABEL_OFFSET + W_MARKER_LABEL); + } + } + + pLabel = new (std::nothrow) Label(); + labelName.Append(__bubbleCount); + + if (pLabel != null) + { + String bubbleName(IDB_SELECTED_BUBBLE_TOP); + Bitmap* pNewBubbleBitmap = null; + Rectangle labelRect(xPos, yPos, W_MARKER_LABEL, H_MARKER_LABEL); + pLabel->Construct(labelRect, L""); + bubbleName.Append(__bubbleCount); + bubbleName.Append(BITMAP_EXTENSION); + pNewBubbleBitmap = ApplicationUtils::GetResourceBitmapN(bubbleName); + + if (pNewBubbleBitmap != null) + { + __pBubbleBitmaps->Add(pNewBubbleBitmap); + } + + pLabel->SetBackgroundBitmap(*static_cast(__pBubbleBitmaps->GetAt(0))); + pLabel->SetTextColor(Color::GetColor(COLOR_ID_BLACK)); + pLabel->SetTextHorizontalAlignment(ALIGNMENT_CENTER); + pLabel->SetTextVerticalAlignment(ALIGNMENT_MIDDLE); + pLabel->SetName(labelName); + pLabel->AddTouchEventListener(*this); + r = AddControl(*pLabel); + __pBubbleLabels->Add(pLabel); + xPos += (W_MARKER_LABEL + X_MARKER_LABEL_OFFSET); + } + return r; +} + +const int +CustomPageMarker::GetBubbleCount(void) +{ + return __bubbleCount; +} + +result +CustomPageMarker::RemoveBubble(int bubbleNo) +{ + result r = E_SUCCESS; + Label* pLabel = static_cast(__pBubbleLabels->GetAt(bubbleNo - 1)); + + if (pLabel != null) + { + RemoveControl(bubbleNo - 1); + __pBubbleLabels->RemoveAt(bubbleNo - 1, false); + __pBubbleBitmaps->RemoveAt(bubbleNo, true); + + for (int bubbleCount = bubbleNo; bubbleCount < __bubbleCount; bubbleCount++) + { + Label* pLabel = static_cast(GetControl(bubbleCount)); + + if (pLabel != null) + { + Point curPos = pLabel->GetPosition(); + curPos.x -= (W_MARKER_LABEL + X_MARKER_LABEL_OFFSET); + pLabel->SetPosition(curPos); + } + } + + RequestRedraw(true); + __bubbleCount--; + } + return r; +} + +void +CustomPageMarker::SetPageMarkerEventListener(ICustomPageMarkerEventListener* pListner) +{ + __pMarkerListener = pListner; + return; +} + +void +CustomPageMarker::SetSelectedBubble(int bubbleNumber) +{ + TryReturnVoid(bubbleNumber != __selectedBubble, "Passed page is already being shown"); + String controlName; + controlName.Append(bubbleNumber); + Label* pLabel = null; + + if (__selectedBubble != 0) + { + String controlName; + controlName.Append(__selectedBubble); + Label* pLabel = static_cast(GetControl(controlName)); + + if (pLabel != null) + { + Bitmap* pBitmapToBeSet = null; + pLabel->SetText(L""); + + pBitmapToBeSet = static_cast(__pBubbleBitmaps->GetAt(0)); + + if (pBitmapToBeSet != null) + { + pLabel->SetBackgroundBitmap(*pBitmapToBeSet); + } + pLabel->RequestRedraw(true); + __selectedBubble = bubbleNumber; + } + } + + pLabel = static_cast(GetControl(controlName)); + + if (pLabel != null) + { + Bitmap* pBitmapToBeSet = null; + pBitmapToBeSet = static_cast(__pBubbleBitmaps->GetAt(bubbleNumber)); + + if (pBitmapToBeSet != null) + { + pLabel->SetBackgroundBitmap(*pBitmapToBeSet); + } + + pLabel->RequestRedraw(true); + __selectedBubble = bubbleNumber; + } + + return; +} + +void +CustomPageMarker::OnTouchReleased(const Control& source, const Point& currentPosition, const TouchEventInfo& touchInfo) +{ + if (__pMarkerListener != null) + { + String controlName = source.GetName(); + + if (!controlName.IsEmpty()) + { + int bubbleNumber = 0; + Integer::Parse(controlName, bubbleNumber); + __pMarkerListener->OnMarkerBubbleMoved(bubbleNumber); + } + } + return; +} diff --git a/src/HmGenericDatabaseManager.cpp b/src/HmGenericDatabaseManager.cpp new file mode 100644 index 0000000..b487ed0 --- /dev/null +++ b/src/HmGenericDatabaseManager.cpp @@ -0,0 +1,679 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmGenericDatabaseManager.cpp + * @brief Keeps the Implementation of GenericDatabaseManager and related interfaces + * declaration of the various functions which may be needed for various database operations + */ + +#include +#include "HmGenericDatabaseManager.h" +#include "HmTypes.h" + +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Io; + +GenericDatabaseManager* GenericDatabaseManager::__pDatabaseManager = null; + +void +GenericDatabaseManager::DestroyInstance(void) +{ + if (__pDatabaseManager != null) + { + delete __pDatabaseManager; + __pDatabaseManager = null; + } +} + +GenericDatabaseManager* +GenericDatabaseManager::GetInstance(void) +{ + if (__pDatabaseManager == null) + { + CreateInstance(); + } + return __pDatabaseManager; +} + +result +GenericDatabaseManager::CreateDataBase(const String& databaseName) +{ + result r = E_INVALID_ARG; + String folderName(databaseName); + int indexOfDirectory = 0; + //Santiy test + TryReturn(!databaseName.IsEmpty(), r, "Invalid argument passed"); + + if (__pDatabase != null) + { + if (__pDatabase->GetName().Equals(databaseName, true)) + { + return E_SUCCESS; + } + else + { + delete __pDatabase; + __pDatabase = null; + } + } + + folderName.LastIndexOf(L'/', databaseName.GetLength() - 1, indexOfDirectory); + folderName.Remove(indexOfDirectory, (folderName.GetLength() - indexOfDirectory)); + Directory::Create(folderName, true); + __pDatabase = new (std::nothrow) Database(); + TryReturn(__pDatabase != null, E_OUT_OF_MEMORY, "unable to allocate memory for Database"); + r = __pDatabase->Construct(databaseName, "a+"); + TryCatch(r == E_SUCCESS, , "__pDatabase->Construct(databaseName, a+) failed with error %s", GetErrorMessage(r)); + + return r; + +CATCH: + + if (__pDatabase != null) + { + delete __pDatabase; + __pDatabase = null; + } + + return r; +} + +result +GenericDatabaseManager::CreateTable(const String& tableName, ArrayList* pColumnNames, ArrayList* pColumnTypes) +{ + result r = E_INVALID_ARG; + + TryReturn((!tableName.IsEmpty() || pColumnNames != null || pColumnTypes != null), r, "Invalid arguments"); + + if (__pDatabase != null) + { + String queryText(CREATE_TABLE); + queryText.Append(tableName); + queryText.Append(L"("); + + for (int paramCount = 0; paramCount < pColumnNames->GetCount(); paramCount++) + { + String* name = static_cast(pColumnNames->GetAt(paramCount)); + String* type = static_cast(pColumnTypes->GetAt(paramCount)); + + queryText.Append(*name); + queryText.Append(L" "); + queryText.Append(*type); + + if (paramCount == pColumnNames->GetCount() - 1) + { + queryText.Append(L")"); + } + else + { + queryText.Append(L","); + } + } + + r = __pDatabase->BeginTransaction(); + + if (r == E_SUCCESS) + { + r = __pDatabase->ExecuteSql(queryText, true); + + if (IsFailed(r)) + { + __pDatabase->RollbackTransaction(); + } + TryReturn(r == E_SUCCESS, r, + "__pDatabase->ExecuteSql(queryStr, true) failed %s", GetErrorMessage(r)); + r = __pDatabase->CommitTransaction(); + TryReturn(r == E_SUCCESS, r, + "__pDatabase->CommitTransaction() failed %s", GetErrorMessage(r)); + } + } + return r; +} + +result +GenericDatabaseManager::DeleteFromTable(const String& tableName, const String& whereCondition) +{ + result r = E_INVALID_ARG; + //sanity test + TryReturn(!tableName.IsEmpty() || !whereCondition.IsEmpty(), r, "Invalid argument passed"); + String query(DELETE_TABLE); + query.Append(tableName); + query.Append(L" "); + query.Append(L"WHERE "); + query.Append(whereCondition); + + if (__pDatabase != null) + { + __pDatabase->BeginTransaction(); + r = __pDatabase->ExecuteSql(query, true); + + if (IsFailed(r)) + { + AppLogException("__pDatabase->ExecuteSql(query,true); returned with %s", GetErrorMessage(r)); + __pDatabase->RollbackTransaction(); + } + else + { + __pDatabase->CommitTransaction(); + } + } + return r; +} + +result +GenericDatabaseManager::GetDataRowFromTable(const String& tableName, const String& whereCondition, Collection::HashMap& rowDataHashMap) +{ + result r = E_SUCCESS; + // Prepare Column info + DbEnumerator* pDbEnumerator = null; + String query = SELECT_TABLE; + + query.Append(tableName); + query.Append(L" "); + query.Append(L"WHERE "); + query.Append(whereCondition); + pDbEnumerator = __pDatabase->QueryN(query); + + if (pDbEnumerator == null) + { + AppLogException("GetDataRowFromTable returning error %s", GetErrorMessage(GetLastResult())); + return GetLastResult(); + } + + pDbEnumerator->MoveNext(); + + for (int paramCount = 0; paramCount < pDbEnumerator->GetColumnCount(); paramCount++) + { + Object* pValue = null; + DbColumnType columnType = pDbEnumerator->GetColumnType(paramCount); + String* pColumnName = null; + + if (columnType == DB_COLUMNTYPE_INT) + { + int tempIntVal = 0; + r = pDbEnumerator->GetIntAt(paramCount, tempIntVal); +// TryContinue(retVal, pValue, +// "pDbEnumerator->GetIntAt failed with error %s",GetErrorMessage(retVal)); + pValue = new (std::nothrow) Integer(tempIntVal); + + if (pValue == null) + { + continue; + } + } + else if (columnType == DB_COLUMNTYPE_INT64) + { + long long tempLongVal = 0; + r = pDbEnumerator->GetInt64At(paramCount, tempLongVal); +// TryContinue(retVal, pLongValue, +// "pDbEnumerator->GetInt64At failed with error %s",GetErrorMessage(retVal)); + pValue = new (std::nothrow) LongLong(tempLongVal); + + if (pValue == null) + { + continue; + } + } + else if (columnType == DB_COLUMNTYPE_DOUBLE) + { + double tempDoubleVal; + r = pDbEnumerator->GetDoubleAt(paramCount, tempDoubleVal); +// TryContinue(retVal, pDoubleValue, +// "pDbEnumerator->GetDoubleAt failed with error %s",GetErrorMessage(retVal)); + pValue = new (std::nothrow) Double(tempDoubleVal); + + if (pValue == null) + { + continue; + } + + } + else if (columnType == DB_COLUMNTYPE_TEXT) + { + String* pTextValue = new (std::nothrow) String(); + + if (pTextValue == null) + { + continue; + } + r = pDbEnumerator->GetStringAt(paramCount, *pTextValue); + + if (IsFailed(r)) + { + delete pTextValue; + pTextValue = null; + continue; + } + pValue = pTextValue; + } + else if (columnType == DB_COLUMNTYPE_BLOB) + { + ByteBuffer* pBlobValue = new (std::nothrow) ByteBuffer(); + + if (pBlobValue == null) + { + continue; + } + + r = pDbEnumerator->GetBlobAt(paramCount, *pBlobValue); + + if (IsFailed(r)) + { + delete pBlobValue; + pBlobValue = null; + continue; + } + + pValue = pBlobValue; + } + + if (pValue != null) + { + pColumnName = new (std::nothrow) String(pDbEnumerator->GetColumnName(paramCount)); + + if (pColumnName == null) + { + delete pValue; + pValue = null; + r = E_OUT_OF_MEMORY; + continue; + } + + r = rowDataHashMap.Add(pColumnName, pValue); + } + } + + delete pDbEnumerator; + pDbEnumerator = null; + + return r; +} + +int +GenericDatabaseManager::GetLastAddedRowID(const String& tableName) +{ + int rowId = -1; + TryReturn(!tableName.IsEmpty(), E_INVALID_ARG, "Invalid arguments"); + + if (__pDatabase != null) + { + String query = GET_LAST_RECORD_ID; + DbEnumerator* pDbEnumerator = null; + query.Append(tableName); + pDbEnumerator = __pDatabase->QueryN(query); + + if (pDbEnumerator != null) + { + while (pDbEnumerator->MoveNext() == E_SUCCESS) + { + for (int paramCount = 0; paramCount < pDbEnumerator->GetColumnCount(); paramCount++) + { + DbColumnType columnType = pDbEnumerator->GetColumnType(paramCount); + + if (columnType == DB_COLUMNTYPE_INT) + { + pDbEnumerator->GetIntAt(paramCount, rowId); + break; + } + } + } + + delete pDbEnumerator; + pDbEnumerator = null; + } + } + + return rowId; +} + +result +GenericDatabaseManager::InsertToTable(const String& tableName, ArrayList* pColumnNames, ArrayList* pColumnTypes, ArrayList* pColumnValues) +{ + result r = E_SUCCESS; + TryReturn((!tableName.IsEmpty() || pColumnNames != null || pColumnValues != null), E_INVALID_ARG, "Invalid arguments"); + + if (__pDatabase != null) + { + DbEnumerator* pDbEnum = null; + DbStatement* pDbStatement = null; + String query(INSERT_TABLE); + query.Append(tableName); + query.Append(L"("); + //Prepare Transaction + r = __pDatabase->BeginTransaction(); + + if (r == E_SUCCESS) + { + for (int paramCount = 0; paramCount < pColumnNames->GetCount(); paramCount++) + { + String* name = static_cast(pColumnNames->GetAt(paramCount)); + query.Append(*name); + + if (paramCount == pColumnNames->GetCount() - 1) + { + query.Append(L")"); + } + else + { + query.Append(L","); + } + } + + query.Append(L" "); + query.Append(L"VALUES"); + query.Append(L" ("); + + for (int paramCount = 0; paramCount < pColumnValues->GetCount(); paramCount++) + { + query.Append(L" ? "); + + if (paramCount == pColumnNames->GetCount() - 1) + { + query.Append(L")"); + } + else + { + query.Append(L","); + } + } + + pDbStatement = __pDatabase->CreateStatementN(query); + + if (pDbStatement != null) + { + for (int colIndex = 0; colIndex < pColumnValues->GetCount(); colIndex++) + { + + Integer* columnInttype = static_cast(pColumnTypes->GetAt(colIndex)); + + DbColumnType columnType = (DbColumnType) columnInttype->ToInt(); + + if (columnType == DB_COLUMNTYPE_INT) + { + Integer* pIntValue = static_cast(pColumnValues->GetAt(colIndex)); + + if (pIntValue != null && pIntValue->ToInt() == -1) + { + pDbStatement->BindNull(colIndex); + } + else + { + pDbStatement->BindInt(colIndex, pIntValue->ToInt()); + } + } + else if (columnType == DB_COLUMNTYPE_INT64) + { + LongLong* pLongValue = static_cast(pColumnValues->GetAt(colIndex)); + pDbStatement->BindInt64(colIndex, pLongValue->ToLong()); + } + else if (columnType == DB_COLUMNTYPE_DOUBLE) + { + Double* pDoubleValue = static_cast(pColumnValues->GetAt(colIndex)); + pDbStatement->BindDouble(colIndex, pDoubleValue->ToDouble()); + } + else if (columnType == DB_COLUMNTYPE_TEXT) + { + String* pTextValue = static_cast(pColumnValues->GetAt(colIndex)); + pDbStatement->BindString(colIndex, *pTextValue); + } + else if (columnType == DB_COLUMNTYPE_BLOB) + { + ByteBuffer* pBlobValue = static_cast(pColumnValues->GetAt(colIndex)); + pDbStatement->BindBlob(colIndex, *pBlobValue); + } + else + { + continue; + } + } + + pDbEnum = __pDatabase->ExecuteStatementN(*pDbStatement); + + if (GetLastResult() == E_SUCCESS) + { + r = __pDatabase->CommitTransaction(); + } + else + { + r = __pDatabase->RollbackTransaction(); + } + + if (IsFailed(r)) + { + AppLogDebug("__pDatabase->CommitTransaction() failed result = %s", GetErrorMessage(r)); + __pDatabase->RollbackTransaction(); + } + + if (pDbStatement != null) + { + delete pDbStatement; + pDbStatement = null; + } + + + if (pDbEnum != null) + { + delete pDbEnum; + pDbEnum = null; + } + } + else + { + r = __pDatabase->RollbackTransaction(); + } + } + else + { + r = __pDatabase->RollbackTransaction(); + } + } + return r; + +} + +result +GenericDatabaseManager::UpdateTable(const String& tableName, ArrayList* pColumnsToModify, ArrayList* pColumnTypes, ArrayList* pColumnsNewData, const String* pWhereCondition) +{ + TryReturn((!tableName.IsEmpty() || pColumnsToModify != null || pColumnsNewData != null || pWhereCondition != null), E_INVALID_ARG, + "Invalid arguments"); + + result r = E_SUCCESS; + String query = UPDATE_TABLE; + query.Append(tableName); + query.Append(L" SET "); + + for (int columnNumber = 0; columnNumber < pColumnsToModify->GetCount(); columnNumber++) + { + String* pColName = static_cast(pColumnsToModify->GetAt(columnNumber)); + query.Append(*pColName); + query.Append(L" = "); + query.Append(L"?"); + + if (columnNumber == pColumnsToModify->GetCount() - 1) + { + query.Append(L" "); + } + else + { + query.Append(L","); + } + } + + query.Append(L"WHERE "); + query.Append(*pWhereCondition); + + if (__pDatabase != null) + { + DbStatement* pDbStatement = null; + + r = __pDatabase->BeginTransaction(); + pDbStatement = __pDatabase->CreateStatementN(query); + + if (pDbStatement != null) + { + DbEnumerator* pDbEnum = null; + + for (int colIndex = 0; colIndex < pColumnsNewData->GetCount(); colIndex++) + { + Integer* columnInttype = static_cast(pColumnTypes->GetAt(colIndex)); + + DbColumnType columnType = (DbColumnType) columnInttype->ToInt(); + + + if (columnType == DB_COLUMNTYPE_INT) + { + Integer* pIntValue = static_cast(pColumnsNewData->GetAt(colIndex)); + pDbStatement->BindInt(colIndex, pIntValue->ToInt()); + } + else if (columnType == DB_COLUMNTYPE_INT64) + { + LongLong* pLongValue = static_cast(pColumnsNewData->GetAt(colIndex)); + pDbStatement->BindInt64(colIndex, pLongValue->ToLong()); + } + else if (columnType == DB_COLUMNTYPE_DOUBLE) + { + Double* pDoubleValue = static_cast(pColumnsNewData->GetAt(colIndex)); + pDbStatement->BindDouble(colIndex, pDoubleValue->ToDouble()); + } + else if (columnType == DB_COLUMNTYPE_TEXT) + { + String* pTextValue = static_cast(pColumnsNewData->GetAt(colIndex)); + if (pTextValue != null) + { + if (pTextValue->IsEmpty()) + { + pDbStatement->BindNull(colIndex); + } + else + { + pDbStatement->BindString(colIndex, *pTextValue); + } + } + } + else if (columnType == DB_COLUMNTYPE_BLOB) + { + ByteBuffer* pBlobValue = static_cast(pColumnsNewData->GetAt(colIndex)); + pDbStatement->BindBlob(colIndex, *pBlobValue); + } + else + { + continue; + } + } + + pDbEnum = __pDatabase->ExecuteStatementN(*pDbStatement); + + if (pDbEnum == null) + { + r = GetLastResult(); + AppLogException("__pDatabase->ExecuteStatementN returned error %s", GetErrorMessage(r)); + } + + if (!IsFailed(r)) + { + r = __pDatabase->CommitTransaction(); + } + + if (pDbEnum != null) + { + if (pDbEnum->GetColumnCount() < 1) + { + r = E_SUCCESS; + } + delete pDbEnum; + pDbEnum = null; + } + if (pDbStatement != null) + { + delete pDbStatement; + pDbStatement = null; + } + } + else + { + r = GetLastResult(); + AppLogException("Create statement failed with error %s", GetErrorMessage(r)); + __pDatabase->RollbackTransaction(); + } + + + } + return r; +} + +GenericDatabaseManager::GenericDatabaseManager(void) + : __pDatabase(null) +{ + //no implementation required +} + +GenericDatabaseManager::~GenericDatabaseManager(void) +{ + if (__pDatabase != null) + { + delete __pDatabase; + } +} + +void +GenericDatabaseManager::CreateInstance(void) +{ + __pDatabaseManager = new (std::nothrow) GenericDatabaseManager(); + + if (__pDatabaseManager != null) + { + std::atexit(DestroyInstance); + } +} + +DbColumnType +GenericDatabaseManager::GetColumnType(DbEnumerator* dbEnumerator, String* pColumnName) +{ + TryReturn(dbEnumerator != null || pColumnName != null, DB_COLUMNTYPE_UNDEFINED, "Invalid parameters passed"); + + for (int columnNumber = 0; columnNumber < dbEnumerator->GetColumnCount(); columnNumber++) + { + String colName = dbEnumerator->GetColumnName(columnNumber); + + if (pColumnName->Equals(colName, false)) + { + return dbEnumerator->GetColumnType(columnNumber); + } + } + + return DB_COLUMNTYPE_UNDEFINED; +} + +int +GenericDatabaseManager::GetColumnIndex(DbEnumerator* dbEnumerator, String* pColumnName) +{ + TryReturn(dbEnumerator != null || pColumnName != null, -1, "Invalid parameters passed"); + + for (int columnNumber = 0; columnNumber < dbEnumerator->GetColumnCount(); columnNumber++) + { + String columnName = dbEnumerator->GetColumnName(columnNumber); + + if (pColumnName->Equals(columnName, false)) + { + return columnNumber; + } + } + + return -1; + +} diff --git a/src/HmHomeApp.cpp b/src/HmHomeApp.cpp new file mode 100644 index 0000000..1fbde71 --- /dev/null +++ b/src/HmHomeApp.cpp @@ -0,0 +1,219 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomeApp.cpp + * @brief Keeps implementation of UiApp derived class. + */ + +#include +#include +#include "HmHomeApp.h" +#include "HmHomeForm.h" +#include "HmMainFrame.h" +#include "HmHomePresentationModel.h" + +using namespace Tizen::App; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::System; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; + + +HomeApp::HomeApp(void) + : __presentationModelInitialized(false) + , __pHomeForm(null) + , __pPresentationModel(null) +{ + //No implementation needed +} + +HomeApp::~HomeApp(void) +{ + //No implementation needed +} + +UiApp* +HomeApp::CreateInstance(void) +{ + // Create the instance through the constructor. + return new (std::nothrow) HomeApp(); +} + +bool +HomeApp::OnAppInitialized(void) +{ + __pHomeForm = null; + MainFrame* pMainFrame = null; + bool retVal = true; + result r = E_SUCCESS; + // Create a Frame + pMainFrame = new (std::nothrow) MainFrame(); + r = pMainFrame->Construct(); + TryCatch(r == E_SUCCESS, retVal = false, " pHmMainFrame.>Construct() failed with error %s", GetErrorMessage(r)); + r = AddFrame(*pMainFrame); + TryCatch(r == E_SUCCESS, retVal = false; + delete pMainFrame; + pMainFrame = null, "AddFrame(*pHmMainFrame. failed with error %s", GetErrorMessage(r)); + // Create a form + __pHomeForm = new (std::nothrow) HomeForm(); + __pHomeForm->Initialize(); + // Add the form to the frame + r = pMainFrame->AddControl(*__pHomeForm); + TryCatch(r == E_SUCCESS, retVal = false, "pHmMainFrame.>AddControl(*__pHomeForm) failed with error %s", GetErrorMessage(r)); + // Set the current form + pMainFrame->SetCurrentForm(*__pHomeForm); + + // Draw the form + __pHomeForm->Draw(); + + if (__presentationModelInitialized) + { + __pHomeForm->InitializePageControls(__pPresentationModel); + } + + return retVal; + +CATCH: + + if (__pHomeForm != null) + { + delete __pHomeForm; + __pHomeForm = null; + } + + if (pMainFrame != null) + { + delete pMainFrame; + pMainFrame = null; + } + return retVal; + +} + + +bool +HomeApp::OnAppInitializing(AppRegistry& appRegistry) +{ + __pPresentationModel = new (std::nothrow) HomePresentationModel(); + __pPresentationModel->Construct(); + return true; +} + +bool +HomeApp::OnAppWillTerminate(void) +{ + // Comment. + return true; +} + + +bool +HomeApp::OnAppTerminating(AppRegistry& appRegistry, bool forcedTermination) +{ + // Deallocate resources allocated by this App for termination. + // The App's permanent data and context can be saved via appRegistry. + return true; +} + +void +HomeApp::OnForeground(void) +{ + if (__pHomeForm != null) + { + __pHomeForm->UpdateAllPages(); + } + + return; +} + +void +HomeApp::OnBackground(void) +{ + // TODO: + // Stop drawing when the application is moved to the background. + return; +} + +void +HomeApp::OnLowMemory(void) +{ + // TODO: + // Free unused resources or close the application. + return; +} + +void +HomeApp::OnBatteryLevelChanged(BatteryLevel batteryLevel) +{ + // TODO: + // Handle any changes in battery level here. + // Stop using multimedia features(camera, mp3 etc.) if the battery level is CRITICAL. + return; +} + +void +HomeApp::OnScreenOn(void) +{ + // TODO: + // Get the released resources or resume the operations that were paused or stopped in OnScreenOff(). + return; +} + +void +HomeApp::OnScreenOff(void) +{ + // TODO: + // Unless there is a strong reason to do otherwise, release resources (such as 3D, media, and sensors) to allow the device + // to enter the sleep mode to save the battery. + // Invoking a lengthy asynchronous method within this listener method can be risky, because it is not guaranteed to invoke a + // callback before the device enters the sleep mode. + // Similarly, do not perform lengthy operations in this listener method. Any operation must be a quick one. + return; +} + +void +HomeApp::OnUserEventReceivedN(RequestId requestId, IList* pArgs) +{ + switch (requestId) + { + case MODEL_REQUEST_INITIALIZE: + { + __presentationModelInitialized = true; + + if (__pHomeForm != null) + { + __pHomeForm->InitializePageControls(__pPresentationModel); + } + } + break; + + default: + { + //no implementation required + } + break; + + } + + if (pArgs != null) + { + pArgs->RemoveAll(true); + delete pArgs; + pArgs = null; + } +} diff --git a/src/HmHomeEntry.cpp b/src/HmHomeEntry.cpp new file mode 100644 index 0000000..6275923 --- /dev/null +++ b/src/HmHomeEntry.cpp @@ -0,0 +1,70 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomeAppEntry.cpp + * @brief This file contains the Tizen application entry point. + */ + +#include "HmHomeApp.h" + +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +_EXPORT_ int OspMain(int argc, char* pArgv[]); + +/** + * The entry function of Tizen application called by the operating system. + */ +int +OspMain(int argc, char* pArgv[]) +{ + result r = E_OUT_OF_MEMORY; + + AppLogDebug("Application started."); + ArrayList* pArgs = new (std::nothrow) ArrayList(); + + if (pArgs == null) + { + return r; + } + + r = pArgs->Construct(); + + TryCatch(r == E_SUCCESS, , "pArgs->Construct() failed with error %s", GetErrorMessage(r)); + + for (int i = 0; i < argc; i++) + { + pArgs->Add((new (std::nothrow) String(pArgv[i]))); + } + + r = Tizen::App::UiApp::Execute(HomeApp::CreateInstance, pArgs); + + TryCatch(r == E_SUCCESS, r &= 0x0000FFFF, "Application execution failed-[%s].", GetErrorMessage(r)); +CATCH: + pArgs->RemoveAll(true); + delete pArgs; + AppLogDebug("Application finished."); + return static_cast(r); +} +#ifdef __cplusplus +} +#endif // __cplusplus diff --git a/src/HmHomeForm.cpp b/src/HmHomeForm.cpp new file mode 100644 index 0000000..abb6e45 --- /dev/null +++ b/src/HmHomeForm.cpp @@ -0,0 +1,659 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomeForm.cpp + * @brief Keeps implementation of Main Form of the application + */ + +#include +#include +#include +#include +#include "HmApplicationUtils.h" +#include "HmHomeForm.h" +#include "HmHomeItemInfo.h" +#include "HmProgressPanel.h" +#include "HmTypes.h" + +using namespace Tizen::App; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Graphics; +using namespace Tizen::System; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Animations; +using namespace Tizen::Ui::Controls; + +HomeForm::HomeForm(void) + : __isEditEnabled(false) + , __isLanguageChanged(false) + , __pPageControl(null) + , __pPageMarker(null) + , __pHomePresentationModel(null) + , __pProgressPanel(null) + , __pBackgroundBitmap(null) + , __pSettingsBitmap(null) + , __pSettingsPressedBitmap(null) + , __pBackgroundLabel(null) + , __pSettingsPanel(null) +{ +} + +HomeForm::~HomeForm(void) +{ + SettingInfo::RemoveSettingEventListener(*this); + + if (__pHomePresentationModel != null) + { + __pHomePresentationModel->SetHomePackageEventListener(null); + delete __pHomePresentationModel; + } + + if (__pBackgroundBitmap != null) + { + delete __pBackgroundBitmap; + __pBackgroundBitmap = null; + } + + if (__pSettingsBitmap != null) + { + delete __pSettingsBitmap; + } + + if (__pSettingsPressedBitmap != null) + { + delete __pSettingsPressedBitmap; + } +} + +bool +HomeForm::Initialize(void) +{ + Construct(L"IDL_FORM"); + return true; +} + +result +HomeForm::InitializePageControls(HomePresentationModel* pPresentationModel) +{ + result r = E_SUCCESS; + + if (__pHomePresentationModel == null) + { + int pageCount = 0; + IconListView* pIconListView = null; + __pHomePresentationModel = pPresentationModel; + __pHomePresentationModel->SetHomePackageEventListener(this); + + pageCount = __pHomePresentationModel->GetPageCount(); + + while (__pPageControl->GetPageCount() < pageCount) + { + __pPageControl->AddPage(); + } + + for (int iconListCount = 0; iconListCount < __pPageControl->GetIconLists()->GetCount(); iconListCount++) + { + pIconListView = static_cast(__pPageControl->GetIconLists()->GetAt(iconListCount)); + pIconListView->UpdateList(); + } + + + if (__pProgressPanel != null) + { + //return value ignored as this is just for showing wait cursor and should not disturb application flow + __pProgressPanel->StopAnimation(); + } + + Invalidate(true); + } + return r; +} + +void +HomeForm::UpdatePage(ArrayList* pPageList) +{ + ArrayList* pIconLists = __pPageControl->GetIconLists(); + + for (int updateCount = 0; updateCount < pPageList->GetCount(); updateCount++) + { + IconListView* pIconList = null; + int pageNumber = static_cast(pPageList->GetAt(updateCount))->ToInt(); + + if ((pageNumber) == pIconLists->GetCount() + 1) + { + __pPageControl->AddPage(); + } + + pIconList = static_cast(pIconLists->GetAt(pageNumber - 1)); + + if (pIconList != null) + { + pIconList->UpdateList(); + } + } + +} + +result +HomeForm::OnInitializing(void) +{ + result r = E_SUCCESS; + String wallPaperPath; + Rectangle clientRectangle = GetClientAreaBounds(); + Rectangle markerRect = GetBounds(); + Rectangle pageRect = GetBounds(); + Label* pSettingLabel = null; + Label* pDoneLabel = null; + __pSettingsPanel = static_cast(GetControl(L"IDC_SETTING_PANEL")); + __pSettingsPanel->SetBounds(X_SETTING_PANEL, Y_SETTING_PANEL, W_SETTING_PANEL, H_SETTING_PANEL); + __pSettingsPanel->SetBackgroundColor(Color(0, 0, 0, 0)); + + SetControlAlwaysOnTop(*__pSettingsPanel, true); + r = SettingInfo::GetValue(SETTINGS_KEY_WALLPAPER, wallPaperPath); + + if (!wallPaperPath.IsEmpty()) + { + __pBackgroundBitmap = ApplicationUtils::GetBitmapN(wallPaperPath); + } + else + { + __pBackgroundBitmap = ApplicationUtils::GetResourceBitmapN(IDB_BACKGROUND_IMAGE); + } + + SettingInfo::GetValue(SETTINGS_KEY_LANGUAGE, __currentLanguage); + r = SettingInfo::AddSettingEventListener(*this); + + if (__pBackgroundBitmap != null) + { + clientRectangle.x = clientRectangle.y = 0; + __pBackgroundLabel = static_cast(GetControl(L"IDC_BACKGROUND_LABEL")); + __pBackgroundLabel->SetBounds(clientRectangle); + __pBackgroundLabel->SetBackgroundBitmap(*__pBackgroundBitmap); + } + + pDoneLabel = static_cast(__pSettingsPanel->GetControl(L"IDC_DONE_LABEL")); + pDoneLabel->SetShowState(false); + pDoneLabel->AddTouchEventListener(*this); + pSettingLabel = static_cast(__pSettingsPanel->GetControl(L"IDC_SETTING_LABEL")); + pSettingLabel->AddTouchEventListener(*this); + __pSettingsPanel->SetControlAlwaysOnTop(*pSettingLabel, true); + + clientRectangle.x = clientRectangle.y = 0; + __pProgressPanel = new (std::nothrow) ProgressPanel(); + r = __pProgressPanel->Construct(clientRectangle); + r = AddControl(*__pProgressPanel); + //return value egnored as this is just for showing wait curser and should not disturb app flow + __pProgressPanel->StartAnimation(); + + clientRectangle = __pSettingsPanel->GetBounds(); + markerRect = GetClientAreaBounds(); + markerRect.height = H_PAGE_MARKER; + markerRect.y = 0; + markerRect.x = X_MARKER_POSITION; //rect.x + rect.width + 2; + markerRect.width -= (2 * W_MARKER_OFFSET); + __pPageMarker = new (std::nothrow) CustomPageMarker(); + r = __pPageMarker->Construct(markerRect, 1); + TryCatch(r == E_SUCCESS, delete __pPageMarker; + __pPageMarker = null, "__pPageMarker->Construct failed with error %s", GetErrorMessage(r)); + __pPageMarker->SetSelectedBubble(1); + __pPageMarker->SetPageMarkerEventListener(this); + r = AddControl(*__pPageMarker); + TryCatch(r == E_SUCCESS, delete __pPageMarker; + __pPageMarker = null, "AddControl failed"); + + pageRect = GetClientAreaBounds(); + pageRect.y = markerRect.height; + pageRect.x = 0; + pageRect.height -= markerRect.height; + + __pPageControl = new (std::nothrow) CustomPageControl(); + r = __pPageControl->Construct(pageRect, 1, pageRect.width); + TryCatch(r == E_SUCCESS, delete __pPageControl; + __pPageControl = null, "__pPageMarker->Construct failed with error %s", GetErrorMessage(r)); + __pPageControl->SetMaxNumberOfIcons(MAX_ICONS_PER_PAGE); + __pPageControl->SetPageControlEventListener(this); + __pPageControl->SetPageControlItemProvider(this); + r = AddControl(*__pPageControl); + TryCatch(r == E_SUCCESS, delete __pPageControl; + __pPageControl = null, "AddControl failed"); + + return r; + +CATCH: + + if (__pPageControl != null) + { + delete __pPageControl; + __pPageControl = null; + } + + if (__pPageMarker != null) + { + delete __pPageMarker; + __pPageMarker = null; + } + + return r; +} + +result +HomeForm::OnTerminating(void) +{ + __pHomePresentationModel->UpdatePageData(); + return E_SUCCESS; +} + +void +HomeForm::OnSettingChanged(String& key) +{ + + if (key.CompareTo(SETTINGS_KEY_WALLPAPER) == 0) + { + result r = E_SUCCESS; + String wallPaperPath; + + r = SettingInfo::GetValue(SETTINGS_KEY_WALLPAPER, wallPaperPath); + + if (!wallPaperPath.IsEmpty() && r == E_SUCCESS) + { + if (__pBackgroundBitmap != null) + { + delete __pBackgroundBitmap; + __pBackgroundBitmap = null; + } + + __pBackgroundBitmap = ApplicationUtils::GetBitmapN(wallPaperPath); + + if (__pBackgroundBitmap != null) + { + __pBackgroundLabel->SetBackgroundBitmap(*__pBackgroundBitmap); + __pBackgroundLabel->Invalidate(false); + } + } + } + else if (key.CompareTo(SETTINGS_KEY_LANGUAGE) == 0) + { + String selectedLang; + SettingInfo::GetValue(SETTINGS_KEY_LANGUAGE, selectedLang); + + if (selectedLang.CompareTo(__currentLanguage) != 0) + { + __currentLanguage = selectedLang; + __isLanguageChanged = true; + __pHomePresentationModel->LanguageChanged(); + + if (UiApp::GetInstance()->GetAppUiState() != APP_UI_STATE_BACKGROUND) + { + ArrayList* pIconLists = null; + Label* pDoneLabel = static_cast(__pSettingsPanel->GetControl(L"IDC_DONE_LABEL")); + + if (pDoneLabel != null) + { + String doneString; + ApplicationUtils::GetStringResource(L"IDS_COM_POP_DONE", doneString); + pDoneLabel->SetText(doneString); + pDoneLabel->Invalidate(false); + } + + pIconLists = __pPageControl->GetIconLists(); + + if (pIconLists != null) + { + for (int iconListCount = 0; iconListCount < pIconLists->GetCount(); iconListCount++) + { + IconListView* pIconListView = static_cast(pIconLists->GetAt(iconListCount)); + if (pIconListView) + { + pIconListView->UpdateList(); + } + } + } + + } + } + } + + return; +} + +void +HomeForm::OnTouchReleased(const Control& source, const Point& currentPosition, const TouchEventInfo& touchInfo) +{ + if (source.GetName().CompareTo(L"IDC_SETTING_LABEL") == 0 + || source.GetName().CompareTo(L"IDC_DONE_LABEL") == 0) + { + Label* pDoneLabel = null; + Label* pSettingLabel = null; + ControlAnimator* pDoneAnimator = null; + ControlAnimator* pSettingLabelAnimator = null; + Bitmap* pBitmap = null; + Point settingPosition(0, 0); + + __isEditEnabled = !__isEditEnabled; + __pPageControl->ToggleEditMode(); + pDoneLabel = static_cast(__pSettingsPanel->GetControl(L"IDC_DONE_LABEL")); + pDoneAnimator = pDoneLabel->GetControlAnimator(); + pDoneAnimator->SetShowState(__isEditEnabled); + pSettingLabel = static_cast(__pSettingsPanel->GetControl(L"IDC_SETTING_LABEL")); + pSettingLabelAnimator = pSettingLabel->GetControlAnimator(); + settingPosition = pSettingLabel->GetPosition(); + + if (__isEditEnabled) + { + settingPosition.x = 0; + } + else + { + settingPosition.x = X_SETTING_PANEL_PRESSED_OFFSET; + } + + if (__isEditEnabled) + { + Canvas* pCanvas = null; + Rectangle settingRectangle = __pSettingsPanel->GetBounds(); + int pointOffset = 0; + int sizeOffset = SIZE_SETTING_LABEL_OFFSET; + + if (__pSettingsPressedBitmap == null) + { + __pSettingsPressedBitmap = ApplicationUtils::GetResourceBitmapN(IDB_SETTING_BUTTON_PRESSED); + } + pBitmap = __pSettingsPressedBitmap; + + settingRectangle.x = pointOffset; + settingRectangle.y = pointOffset; + settingRectangle.width -= sizeOffset; + settingRectangle.height -= sizeOffset; + + pCanvas = __pSettingsPanel->GetCanvasN(); + + if (pCanvas != null) + { + pCanvas->SetBackgroundColor(Color(0, 0, 0, 0)); + pCanvas->Clear(); + pCanvas->SetBackgroundColor(Color::GetColor(COLOR_ID_BLACK)); + pCanvas->SetLineWidth(1); + pCanvas->SetForegroundColor(Color::GetColor(COLOR_ID_BLACK)); + pCanvas->DrawRectangle(settingRectangle); + pCanvas->SetForegroundColor(COLOR_SETTING_BOUNDARY_INNER); + + pointOffset = sizeOffset; + sizeOffset = 2 * SIZE_SETTING_LABEL_OFFSET; + settingRectangle.x = pointOffset; + settingRectangle.y = pointOffset; + settingRectangle.width -= sizeOffset; + settingRectangle.height -= sizeOffset; + pCanvas->DrawRectangle(settingRectangle); + + pointOffset = sizeOffset; + settingRectangle.x = pointOffset; + settingRectangle.y = pointOffset; + settingRectangle.width -= sizeOffset; + settingRectangle.height -= sizeOffset; + pCanvas->FillRectangle(Color::GetColor(COLOR_ID_BLACK), settingRectangle); + delete pCanvas; + } + } + else + { + Canvas* pCanvas = null; + + if (__pSettingsBitmap == null) + { + __pSettingsBitmap = ApplicationUtils::GetResourceBitmapN(IDB_SETTING_BUTTON_PRESSED); + } + + pBitmap = __pSettingsBitmap; + pCanvas = __pSettingsPanel->GetCanvasN(); + + if (pCanvas != null) + { + pCanvas->SetBackgroundColor(Color(0, 0, 0, 0)); + pCanvas->Clear(); + delete pCanvas; + } + } + + pSettingLabel->SetBackgroundBitmap(*pBitmap); + pSettingLabel->Invalidate(false); + pSettingLabelAnimator->SetPosition(settingPosition); + settingPosition.x += pSettingLabel->GetSize().width; + pDoneAnimator->SetPosition(settingPosition); + } +} + +void +HomeForm::OnPageSwept(int pageNumber) +{ + if (pageNumber > 0) + { + __pPageMarker->SetSelectedBubble(pageNumber); + } + + return; +} + +void +HomeForm::OnPageAdded(int pageNumber) +{ + // adds a new bubble and sets the newly added page as the current page + if (__pPageMarker != null) + { + __pPageMarker->AddBubble(); + } + + return; +} + +void +HomeForm::OnPageRemoved(int pageNumber) +{ + if (__pPageMarker != null) + { + __pPageMarker->RemoveBubble(pageNumber); + } + + return; +} + +void +HomeForm::OnMarkerBubbleMoved(int bubbleNumber) +{ + if (bubbleNumber > 0) + { + __pPageMarker->SetSelectedBubble(bubbleNumber); + __pPageControl->SetPageSelected(bubbleNumber); + } + + return; +} + +void +HomeForm::OnInstallationCompleted(const HomeItemInfo& pItemInfo) +{ + ArrayList* pIconViews = null; + int pageNumber = 0; + int position = 0; + + if (__pHomePresentationModel->GetPageCount() > __pPageControl->GetPageCount()) + { + //__pPageControl->SetAppInfoList(__pDataModel->GetApplicationsList()); + + if (IsFailed(__pPageControl->AddPage())) + { + return; + } + } + + pIconViews = __pPageControl->GetIconLists(); + + if (pIconViews != null) + { + IconListView* pListView = null; + pItemInfo.GetPositionInHomeScreen(pageNumber, position); + pListView = static_cast(pIconViews->GetAt(pageNumber - 1)); + + if (pListView != null) + { + pListView->UpdateList(); + } + } + + return; +} + +void +HomeForm::OnAppUninstallRequested(HomeItemInfo* pItemInfo) +{ + if (__pProgressPanel != null) + { + __pProgressPanel->StartAnimation(); + } + + return; +} + +void +HomeForm::OnUnInstallationCompleted(const HomeItemInfo& pItemInfo) +{ + if (__pHomePresentationModel != null) + { + int pageNumber = 0; + int appIndex = 0; + IconListView* pIconList = null; + ArrayList* pIconLists = __pPageControl->GetIconLists(); + + if (__pProgressPanel != null) + { + __pProgressPanel->StopAnimation(); + } + + pItemInfo.GetPositionInHomeScreen(pageNumber, appIndex); + pIconList = static_cast(pIconLists->GetAt(pageNumber - 1)); + + if (pIconList != null) + { + pIconList->UpdateList(); + } + } + + return; +} + +void +HomeForm::OnUpdatePageRequestedN(Tizen::Base::Collection::ArrayList* pPageList) +{ + if (pPageList != null) + { + UpdatePage(pPageList); + pPageList->RemoveAll(true); + delete pPageList; + pPageList = null; + } + return; +} + +// from IPageControlItemProvider +int +HomeForm::GetPageCount(void) +{ + int pageCount = 0; + + if (__pHomePresentationModel != null) + { + pageCount = __pHomePresentationModel->GetPageCount(); + } + return pageCount; +} + +int +HomeForm::GetItemCount(int pageNumber) +{ + int itemCount = 0; + + if (__pHomePresentationModel != null) + { + itemCount = __pHomePresentationModel->GetItemCount(pageNumber); + +// if(itemCount == 0) +// { +// if(pageNumber > 1) +// { +// __pPageControl->MarkPageToDelete(pageNumber); +// } +// } + } + + return itemCount; +} + +HomeItemInfo* +HomeForm::GetItem(int pageNumber, int index) +{ + HomeItemInfo* itemInfo = null; + + if (__pHomePresentationModel != null) + { + itemInfo = __pHomePresentationModel->GetItem(pageNumber, index); + } + + return itemInfo; +} + +void +HomeForm::RearrangeItems(HomeItemInfo* pMovedAppInfo, int newPageNumber, int newIndex) +{ + __pHomePresentationModel->RearrangeItems(pMovedAppInfo, newPageNumber, newIndex); + return; +} + +void +HomeForm::UpdateAllPages(void) +{ + if (__isLanguageChanged) + { + Label* pDoneLabel = static_cast(__pSettingsPanel->GetControl(L"IDC_DONE_LABEL")); + + if (pDoneLabel != null) + { + String doneString; + ApplicationUtils::GetStringResource(L"IDS_COM_POP_DONE", doneString); + pDoneLabel->SetText(doneString); + pDoneLabel->Invalidate(false); + } + + if (__pPageControl != null) + { + ArrayList* pIconLists = __pPageControl->GetIconLists(); + + if (pIconLists != null) + { + for (int iconListCount = 0; iconListCount < pIconLists->GetCount(); iconListCount++) + { + IconListView* pIconListView = static_cast(pIconLists->GetAt(iconListCount)); + if (pIconListView) + { + pIconListView->UpdateList(); + } + } + } + } + + __isLanguageChanged = false; + } +} diff --git a/src/HmHomeItemInfo.cpp b/src/HmHomeItemInfo.cpp new file mode 100644 index 0000000..4fd452b --- /dev/null +++ b/src/HmHomeItemInfo.cpp @@ -0,0 +1,187 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomeItemInfo.cpp + * @brief Keeps implementation of the HomeItemInfo + * Implements the HomeItemInfo class, it keeps the information of all the applications installed. + */ + +#include +#include +#include "HmHomeItemInfo.h" +#include "HmTypes.h" + +using namespace Tizen::App; +using namespace Tizen::App::Package; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Graphics; + +HomeItemInfo::HomeItemInfo(void) + : __isVisibleInMainMenu(false) + , __isUninstallable(false) + , __pageNumber(0) + , __position(-1) + , __pAppIcon(null) +{ + // No implementation needed + +} + +HomeItemInfo::~HomeItemInfo(void) +{ + // No implementation needed +} + +String +HomeItemInfo::GetAppId(void) const +{ + // returns application id + return __appId; +} + +Bitmap* +HomeItemInfo::GetApplicationIcon(void) const +{ + // returns the application icon + return __pAppIcon; +} + +String +HomeItemInfo::GetAppName(void) const +{ + // returns the name of the application + return __appName; +} + +String +HomeItemInfo::GetIconPath(void) const +{ + // returns the path of the application icon + return __appIconPath; +} + +String +HomeItemInfo::GetPackageId(void) const +{ + // returns package id + return __packageId; +} + +void +HomeItemInfo::GetPositionInHomeScreen(int& pageNumber, int& position) const +{ + pageNumber = __pageNumber; + position = __position; + return; +} + +result +HomeItemInfo::Initialize(PackageAppInfo* pPackAppInfo, PackageInfo* pPackInfo) +{ + TryReturn(pPackAppInfo != null && pPackInfo != null, E_INVALID_ARG, "Invalid arguments"); + + result r = E_SUCCESS; + + __isVisibleInMainMenu = pPackAppInfo->IsMenuIconVisible(); + + if (__isVisibleInMainMenu) + { + // gets the path of the icon if icon is available + String appIconPath = pPackAppInfo->GetAppMenuIconPath(); + + // sets the icon path if icon path is not empty + if (!appIconPath.IsEmpty() && !appIconPath.Equals(L"(null)", true)) + { + __appIconPath = appIconPath; + } +// // sets the icon path if icon path is empty temporarily. +// else +// { +// __appIconPath = IDB_DEFAULT_APP_ICON; +// } + + // gets the application id + AppId appId = pPackAppInfo->GetAppId(); + // sets the application Id + if (!appId.IsEmpty()) + { + __appId = appId; + } + + // gets the application name + String appName = pPackAppInfo->GetAppDisplayName(); + // sets the application name + if (!appName.IsEmpty()) + { + __appName = appName; + } + } + + __isUninstallable = pPackInfo->IsUninstallable(); + __packageId = pPackInfo->GetId(); + + return r; +} + +bool +HomeItemInfo::IsUnistallable(void) const +{ + // returns true if application is uninstallable else false + return __isUninstallable; +} + +bool +HomeItemInfo::IsVisibleInMainMenu(void) const +{ + // returns true if application icon can be shown in home else false + return __isVisibleInMainMenu; +} + +void +HomeItemInfo::SetApplicationIcon(Bitmap* pAppIconBitmap) +{ + // sets the icon for the application + if (__pAppIcon != null) + { + delete __pAppIcon; + __pAppIcon = null; + } + __pAppIcon = pAppIconBitmap; + return; +} + +void +HomeItemInfo::SetApplicationName(String& newAppName) +{ + __appName = newAppName; +} + +void +HomeItemInfo::SetItemIndex(int newIndex) +{ + __position = newIndex; +} + +void +HomeItemInfo::SetPositionInHomeScreen(int pageNumber, int position) +{ + // sets the position of the application icon + __pageNumber = pageNumber; + __position = position; + return; +} diff --git a/src/HmHomePresentationModel.cpp b/src/HmHomePresentationModel.cpp new file mode 100644 index 0000000..b7274f8 --- /dev/null +++ b/src/HmHomePresentationModel.cpp @@ -0,0 +1,1295 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmHomePresentationModel.cpp + * @brief Keeps implementation of the HmHomePresentationModel + * Implements the HmHomePresentationModel class, it keeps the data required to show the application icons in the home view + */ + +#include +#include +#include +#include "HmHomeItemInfo.h" +#include "HmHomePresentationModel.h" + +using namespace Tizen::App; +using namespace Tizen::App::Package; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Io; + +HomePresentationModel::HomePresentationModel(void) + : __pDataBaseManager(null) + , __pDataListener(null) + , __totalApps(0) + , __totalPages(0) + , __pPackMgr(null) + , __pAppHashMap(null) + , __pPackageInfoRetrieveThread(null) +{ + //empty implementation +} + +HomePresentationModel::~HomePresentationModel(void) +{ + __pPackMgr->RemovePackageInstallationEventListener(*this); + + if (__pPackageInfoRetrieveThread != null) + { + __pPackageInfoRetrieveThread->Join(); + delete __pPackageInfoRetrieveThread; + __pPackageInfoRetrieveThread = null; + } + + if (__pAppHashMap != null) + { + IList* pKeysList = __pAppHashMap->GetKeysN(); + + for (int keyCount = 0; keyCount < pKeysList->GetCount(); keyCount++) + { + ArrayList* pAppList = static_cast(__pAppHashMap->GetValue(*static_cast(pKeysList->GetAt(keyCount)))); + + if (pAppList != null) + { + pAppList->RemoveAll(true); + } + } + + pKeysList->RemoveAll(); + delete pKeysList; + __pAppHashMap->RemoveAll(true); + delete __pAppHashMap; + __pAppHashMap = null; + } + + __pDataListener = null; +} + +result +HomePresentationModel::Construct(void) +{ + result r = E_SUCCESS; + __totalPages = 1; + __pPackageInfoRetrieveThread = new (std::nothrow) PackageInfoListRetrieveThread(this); + r = __pPackageInfoRetrieveThread->Construct(); + TryCatch(r == E_SUCCESS, , "__pPackageInfoRetrieveThread->Construct()", GetErrorMessage(r)); + __pPackMgr = PackageManager::GetInstance(); + __pPackMgr->AddPackageInstallationEventListener(*this); + r = __pPackageInfoRetrieveThread->SetPackageType(); + +CATCH: + + return r; +} + +HomeItemInfo* +HomePresentationModel::GetItem(int pageNumber, int index) const +{ + ArrayList* pAppsList = static_cast(__pAppHashMap->GetValue(Integer(pageNumber))); + if (pAppsList != null) + { + return static_cast(pAppsList->GetAt(index)); + } + return null; +} + +int +HomePresentationModel::GetItemCount(int pageNumber) const +{ + if (__pAppHashMap != null) + { + ArrayList* pAppsList = static_cast(__pAppHashMap->GetValue(Integer(pageNumber))); + + if (pAppsList != null) + { + return pAppsList->GetCount(); + } + } + return 0; +} + +int +HomePresentationModel::GetPageCount(void) const +{ + return __totalPages; +} + +void +HomePresentationModel::LanguageChanged(void) +{ + IList* pAppsValues = null; + IEnumerator* pMapEnum = null; + TryCatch(__pAppHashMap != null, , "__pAppHashMap is null"); + pAppsValues = __pAppHashMap->GetValuesN(); + TryCatch(pAppsValues != null, , "pAppHashMap->GetValuesN returned null"); + pMapEnum = pAppsValues->GetEnumeratorN(); + TryCatch(pMapEnum != null, , "pAppsValues->GetEnumeratorN() returned null"); + __pPackMgr = PackageManager::GetInstance(); + + while (pMapEnum->MoveNext() == E_SUCCESS) + { + ArrayList* pAppsArrayList = static_cast(pMapEnum->GetCurrent()); + + if (pAppsArrayList != null) + { + IEnumerator* pAppsEnum = pAppsArrayList->GetEnumeratorN(); + + if (pAppsEnum) + { + while (pAppsEnum->MoveNext() == E_SUCCESS) + { + HomeItemInfo* pAppInfo = static_cast(pAppsEnum->GetCurrent()); + + if (pAppInfo != null) + { + PackageInfo* pPackInfo = __pPackMgr->GetPackageInfoN(pAppInfo->GetPackageId()); + + if (pPackInfo != null) + { + PackageAppInfo* pPackageAppInfo = pPackInfo->GetPackageAppInfoN(pAppInfo->GetAppId()); + + if (pPackageAppInfo != null) + { + String appNewName = pPackageAppInfo->GetAppDisplayName(); + + if (pAppInfo->GetAppName().CompareTo(appNewName) != 0) + { + pAppInfo->SetApplicationName(appNewName); + pAppInfo->SetApplicationIcon(null); + } + + delete pPackageAppInfo; + pPackageAppInfo = null; + } + + delete pPackInfo; + pPackInfo = null; + } + } + } + + delete pAppsEnum; + pAppsEnum = null; + } + } + } + +CATCH: + if (pMapEnum != null) + { + delete pMapEnum; + pMapEnum = null; + } + if (pAppsValues != null) + { + pAppsValues->RemoveAll(false); + delete pAppsValues; + pAppsValues = null; + } +} + +void +HomePresentationModel::RearrangeItems(HomeItemInfo* pMovedAppInfo, int newPageNumber, int newIndex) +{ + ArrayList* pMovedToAppList = null; + ArrayList* pMovedFromAppList = null; + ArrayList* pPagesToUpdate = null; + Integer* pPageToUpdate = null; + result r = E_SUCCESS; + int movedPageNumber = 0; + int movedAppIndex = 0; + // gets the list of applications for the current page + pMovedToAppList = static_cast(__pAppHashMap->GetValue(Integer(newPageNumber))); + pMovedAppInfo->GetPositionInHomeScreen(movedPageNumber, movedAppIndex); + pMovedFromAppList = static_cast(__pAppHashMap->GetValue(Integer(movedPageNumber))); + + if ((newPageNumber == movedPageNumber) && (newIndex == movedAppIndex)) + { + return; + } + + pPagesToUpdate = new ArrayList(); + pPagesToUpdate->Construct(); + pPageToUpdate = new (std::nothrow) Integer(movedPageNumber); + r = pPagesToUpdate->Add(pPageToUpdate); + + if (r != E_SUCCESS) + { + delete pPageToUpdate; + pPageToUpdate = null; + } + + + if (movedPageNumber != newPageNumber) + { + pPageToUpdate = new (std::nothrow) Integer(newPageNumber); + r = pPagesToUpdate->Add(pPageToUpdate); + + if (r != E_SUCCESS) + { + delete pPageToUpdate; + pPageToUpdate = null; + } + } + + if (pMovedToAppList != null && pMovedFromAppList != null) + { + { + if (movedPageNumber == newPageNumber) + { + + if (newIndex != -1 && movedAppIndex != newIndex) + { + + if (newIndex - movedAppIndex == 1) + { + pMovedToAppList->InsertAt(pMovedAppInfo, newIndex + 1); + } + else + { + pMovedToAppList->InsertAt(pMovedAppInfo, newIndex); + } + + if (newIndex > movedAppIndex) + { + pMovedFromAppList->RemoveAt(movedAppIndex); + } + else + { + pMovedFromAppList->RemoveAt(movedAppIndex + 1); + } + + UpdatePositions(*pMovedFromAppList); + } + } + else + { + int numberOfIconsInPage = pMovedToAppList->GetCount(); + + if (numberOfIconsInPage < MAX_ICONS_PER_PAGE) + { + pMovedAppInfo->SetPositionInHomeScreen(newPageNumber, newIndex); + pMovedToAppList->InsertAt(pMovedAppInfo, newIndex); + pMovedFromAppList->RemoveAt(movedAppIndex, false); + UpdatePositions(*pMovedFromAppList); + UpdatePositions(*pMovedToAppList); + } + else if (numberOfIconsInPage >= MAX_ICONS_PER_PAGE) + { + bool foundLocation = false; + int nextPageNumber = 0; + ArrayList* pNextPageAppList = null; + HomeItemInfo* pItemToGetANewLocationFor = static_cast(pMovedToAppList->GetAt(pMovedToAppList->GetCount() - 1)); + pMovedToAppList->Remove(*pItemToGetANewLocationFor, false); + pMovedAppInfo->SetPositionInHomeScreen(newPageNumber, newIndex); + pMovedToAppList->InsertAt(pMovedAppInfo, newIndex); + pMovedFromAppList->Remove(*pMovedAppInfo, false); + + if (pItemToGetANewLocationFor != null) + { + nextPageNumber = newPageNumber + 1; + // checks for the successor page having the number of icons not exceeding its maximum limit + + while (nextPageNumber <= __totalPages) + { + pNextPageAppList = static_cast(__pAppHashMap->GetValue(Integer(nextPageNumber))); + + if (pNextPageAppList->GetCount() < MAX_ICONS_PER_PAGE /*|| nextPageNumber == pageNumber*/) + { + pItemToGetANewLocationFor->SetPositionInHomeScreen(nextPageNumber, pNextPageAppList->GetCount()); + pNextPageAppList->Add(pItemToGetANewLocationFor); + UpdatePositions(*pNextPageAppList); + foundLocation = true; + pPageToUpdate = new Integer(nextPageNumber); + pPagesToUpdate->Add(pPageToUpdate); + break; + } + + nextPageNumber++; + } + + if (!foundLocation && __totalPages < MAX_PAGE_COUNT) + { + result r = E_SUCCESS; + Integer* pPageNumber = null; + ArrayList* pNewAppList = new (std::nothrow) ArrayList(); + pNewAppList->Construct(); + + __totalPages++; + pItemToGetANewLocationFor->SetPositionInHomeScreen(__totalPages, 0); + pNewAppList->Add(pItemToGetANewLocationFor); + pPageNumber = new (std::nothrow) Integer(__totalPages); + r = __pAppHashMap->Add(pPageNumber, pNewAppList); + pPagesToUpdate->Add(new (std::nothrow) Integer(__totalPages)); + + if (IsFailed(r)) + { + delete pPageNumber; + pPageNumber = null; + delete pNewAppList; + pNewAppList = null; + } + + pPageToUpdate = new Integer(__totalPages); + pPagesToUpdate->Add(pPageToUpdate); + foundLocation = true; + } + + if (pNextPageAppList != null) + { + UpdatePositions(*pNextPageAppList); + } + + UpdatePositions(*pMovedFromAppList); + UpdatePositions(*pMovedToAppList); + } + } + } + } + } + + __pDataListener->OnUpdatePageRequestedN(pPagesToUpdate); + return; +} + +void +HomePresentationModel::SetHomePackageEventListener(IHomePresentationModelEventListener* pListener) +{ + __pDataListener = pListener; +} + +result +HomePresentationModel::UpdatePageData(void) +{ + result r = E_INVALID_ARG; + + if (__pAppHashMap != null) + { + IList* pKeys = __pAppHashMap->GetKeysN(); + + if (pKeys != null) + { + for (int pageCount = 0; pageCount < pKeys->GetCount(); pageCount++) + { + ArrayList* pPageApps = (ArrayList*) __pAppHashMap->GetValue(*pKeys->GetAt(pageCount)); + + if (pPageApps != null) + { + + for (int appsCount = 0; appsCount < pPageApps->GetCount(); appsCount++) + { + HomeItemInfo* pItemInfo = static_cast(pPageApps->GetAt(appsCount)); + + if (pItemInfo != null) + { + r = UpdateDataToDatabase(static_cast(pItemInfo)); + } + } + } + } + + pKeys->RemoveAll(false); + delete pKeys; + pKeys = null; + } + } + + return r; +} + +result +HomePresentationModel::HomeApplicationsComparer::Compare(const Object& obj1, const Object& obj2, int& cmp) const +{ + result r = E_FAILURE; + const HomeItemInfo* pObj1 = static_cast(&obj1); + const HomeItemInfo* pObj2 = static_cast(&obj2); + + if (pObj1 != null && pObj2 != null) + { + int pageIndex1 = 0; + int pageNumber = 0; + int pageIndex2 = 0; + pObj1->GetPositionInHomeScreen(pageNumber, pageIndex1); + pObj2->GetPositionInHomeScreen(pageNumber, pageIndex2); + + cmp = Integer::Compare(pageIndex1, pageIndex2); + r = E_SUCCESS; + } + + return r; +} + +void +HomePresentationModel::OnPackageInstallationCompleted(const PackageId& packageId, PackageInstallationResult installationResult) +{ + if (installationResult == PACKAGE_INSTALLATION_RESULT_SUCCESS) + { + NotifyInstallationEvent(packageId); + } + else + { + //Show error + } + return; +} + +void +HomePresentationModel::OnPackageUninstallationCompleted(const PackageId& packageId, bool uninstallationResult) +{ + ArrayList* pAppsList = null; + HomeItemInfo* pItemInfo = null; + + if (uninstallationResult) + { + if (__pDataListener != null && !packageId.IsEmpty()) + { + + pItemInfo = FindAppObjectInList(packageId); + do + { + if (pItemInfo != null) + { + int pageNumber = 0; + int appIndex = 0; + pItemInfo->GetPositionInHomeScreen(pageNumber, appIndex); + pAppsList = static_cast(__pAppHashMap->GetValue(Integer(pageNumber))); + pAppsList->Remove(*pItemInfo); + UpdatePositions(*pAppsList); + if (pItemInfo->IsVisibleInMainMenu()) + { + __pDataListener->OnUnInstallationCompleted(*pItemInfo); + } + + if (pItemInfo != null) + { + delete pItemInfo; + pItemInfo = null; + } + pItemInfo = FindAppObjectInList(packageId); + } + } + while (pItemInfo != null); + } + } + else + { + //Show error + } + + return; +} + +void +HomePresentationModel::OnPackageInfoRetrievedN(Tizen::Base::Collection::HashMap* pAppsList, int totalApps, int totalPages) +{ + UiApp* pApp = UiApp::GetInstance(); + + if (pAppsList != null && totalApps != 0) + { + result r = E_SUCCESS; + __pAppHashMap = pAppsList; + __totalPages = totalPages; + __totalApps = totalApps; + r = PrepareApplicationsList(); + + if (pApp != null) + { + ArrayList* pListToSend = new (std::nothrow) ArrayList(); + + if (pListToSend != null) + { + r = pListToSend->Construct(); + + if (r == E_SUCCESS) + { + Integer* pResToSend = new (std::nothrow) Integer(r); + r = pListToSend->Add(pResToSend); + + if (r == E_SUCCESS) + { + r = pApp->SendUserEvent(MODEL_REQUEST_INITIALIZE, pListToSend); + return; + } + else + { + delete pResToSend; + delete pListToSend; + } + } + } + } + } + + if (pApp != null) + { + pApp->SendUserEvent(MODEL_REQUEST_INITIALIZE, null); + } + + return; +} + +HomeItemInfo* +HomePresentationModel::FindAppObjectInList(const Tizen::Base::String& packageIdToFind) +{ + IList* pKeysList = __pAppHashMap->GetKeysN(); + + if (pKeysList != null) + { + for (int keysCount = 0; keysCount < pKeysList->GetCount(); keysCount++) + { + ArrayList* pList = static_cast(__pAppHashMap->GetValue(*static_cast(pKeysList->GetAt(keysCount)))); + + for (int itemCount = (pList->GetCount() - 1); itemCount >= 0; itemCount--) + { + HomeItemInfo* pApplicationInfo = static_cast(pList->GetAt(itemCount)); + + if (pApplicationInfo != null) + { + String packageId = pApplicationInfo->GetPackageId(); + + if (packageId.CompareTo(packageIdToFind) == 0) + { + pKeysList->RemoveAll(); + delete pKeysList; + return static_cast(pApplicationInfo); + } + } + } + } + pKeysList->RemoveAll(); + delete pKeysList; + pKeysList = null; + } + + return null; + +} + +result +HomePresentationModel::InitializeDatabase(void) +{ + result r = E_SUCCESS; + + __pDataBaseManager = GenericDatabaseManager::GetInstance(); + + if (__pDataBaseManager != null) + { + ArrayList* pColumnNames = null; + ArrayList* pColumnTypes = null; + String* pTempColumnData = null; + + String databaseName = App::GetInstance()->GetAppRootPath(); + databaseName.Append(HOME_DATABASE_NAME); + + r = __pDataBaseManager->CreateDataBase(databaseName); + TryCatch(r == E_SUCCESS, , + "Home_Exception::failed to create Database"); + pColumnNames = new (std::nothrow) ArrayList(); + pColumnNames->Construct(); + pColumnTypes = new (std::nothrow) ArrayList(); + pColumnTypes->Construct(); + + //Creates table homeapps + pTempColumnData = new (std::nothrow) String(APPS_RECORD_ID); + r = pColumnNames->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnNames->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + pTempColumnData = new (std::nothrow) String(DATATYPE_INTEGER_PRIMARY); + r = pColumnTypes->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnTypes->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + + pTempColumnData = new (std::nothrow) String(APPS_APP_ID); + r = pColumnNames->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnNames->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + pTempColumnData = new (std::nothrow) String(DATATYPE_TEXT); + pTempColumnData->Append(DATATYPE_UNIQUE); + r = pColumnTypes->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnTypes->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + + pTempColumnData = new (std::nothrow) String(APPS_APP_NAME); + r = pColumnNames->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnNames->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + pTempColumnData = new (std::nothrow) String(DATATYPE_TEXT); + r = pColumnTypes->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnTypes->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + + pTempColumnData = new (std::nothrow) String(APPS_APP_ICON); + r = pColumnNames->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnNames->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + pTempColumnData = new (std::nothrow) String(DATATYPE_TEXT); + r = pColumnTypes->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnTypes->Add(*pTempColumnData) failed with error %s", GetErrorMessage(r)); + + pTempColumnData = new (std::nothrow) String(APPS_APP_PAGE); + r = pColumnNames->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnNames->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + pTempColumnData = new (std::nothrow) String(DATATYPE_INTEGER); + r = pColumnTypes->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnTypes->Add(*pTempColumnData) failed with error %s", GetErrorMessage(r)); + + pTempColumnData = new (std::nothrow) String(APPS_APP_PAGEINDEX); + r = pColumnNames->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnNames->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + pTempColumnData = new (std::nothrow) String(DATATYPE_INTEGER); + r = pColumnTypes->Add(pTempColumnData); + TryCatch(r == E_SUCCESS, delete pTempColumnData; + pTempColumnData = null, + "pColumnTypes->Add(pTempColumnData) failed with error %s", GetErrorMessage(r)); + + r = __pDataBaseManager->CreateTable(HOME_APPLICATIONS_TABLE, pColumnNames, pColumnTypes); + TryCatch(r == E_SUCCESS, , "HmDatabaseManager::CreateTable failed with error %s", GetErrorMessage(r)); +CATCH: + if (pColumnNames != null) + { + pColumnNames->RemoveAll(true); + delete pColumnNames; + pColumnNames = null; + } + + if (pColumnTypes != null) + { + pColumnTypes->RemoveAll(true); + delete pColumnTypes; + pColumnTypes = null; + } + } + return r; +} + +result +HomePresentationModel::InsertPageDataInDataBase(const HomeItemInfo* pItemInfo) +{ + + result r = E_INVALID_ARG; + + if (pItemInfo != null) + { + ArrayList* pColumnNames = null; + ArrayList* pColumnTypes = null; + ArrayList* pColumnValues = null; + String* pTempString = null; + Integer* pTempInt = null; + int pageNumber = 0; + int pageIndex = 0; + + //Constructing various array list + pColumnNames = new (std::nothrow) ArrayList(); + pColumnNames->Construct(); + pColumnTypes = new (std::nothrow) ArrayList(); + pColumnTypes->Construct(); + pColumnValues = new (std::nothrow) ArrayList(); + pColumnValues->Construct(); + + pItemInfo->GetPositionInHomeScreen(pageNumber, pageIndex); + + //Application app id + pTempString = new (std::nothrow) String(APPS_APP_ID); + r = pColumnNames->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(DB_COLUMNTYPE_TEXT); + r = pColumnTypes->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnTypes->Add(pTempInt); failed %s", GetErrorMessage(r)); + pTempString = new (std::nothrow) String(pItemInfo->GetAppId()); + r = pColumnValues->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + + //Application Name + pTempString = new (std::nothrow) String(APPS_APP_NAME); + r = pColumnNames->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(DB_COLUMNTYPE_TEXT); + r = pColumnTypes->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnTypes->Add(pTempInt); failed %s", GetErrorMessage(r)); + pTempString = new (std::nothrow) String(pItemInfo->GetAppName()); + r = pColumnValues->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + + //Application IconPath + pTempString = new (std::nothrow) String(APPS_APP_ICON); + r = pColumnNames->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(DB_COLUMNTYPE_TEXT); + r = pColumnTypes->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnTypes->Add(pTempInt); failed %s", GetErrorMessage(r)); + pTempString = new (std::nothrow) String(pItemInfo->GetIconPath()); + r = pColumnValues->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + + //Application pageNumber + pTempString = new (std::nothrow) String(APPS_APP_PAGE); + r = pColumnNames->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(DB_COLUMNTYPE_INT); + r = pColumnTypes->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnTypes->Add(pTempInt); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(pageNumber); + r = pColumnValues->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnValues->Add(pTempInt); failed %s", GetErrorMessage(r)); + //Application pageIndex + pTempString = new (std::nothrow) String(APPS_APP_PAGEINDEX); + r = pColumnNames->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(DB_COLUMNTYPE_INT); + r = pColumnTypes->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnTypes->Add(pTempInt); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(pageIndex); + r = pColumnValues->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnValues->Add(pTempInt); failed %s", GetErrorMessage(r)); + + //update +// whereCondition = new (std::nothrow)String(APPS_APP_ID); +// whereCondition->Append(L" = "); +// whereCondition->Append(*pItemInfo->GetAppId()); + r = __pDataBaseManager->InsertToTable(HOME_APPLICATIONS_TABLE, pColumnNames, pColumnTypes, pColumnValues); + +CATCH: + + if (pColumnNames != null) + { + pColumnNames->RemoveAll(true); + delete pColumnNames; + pColumnNames = null; + } + + if (pColumnTypes != null) + { + pColumnTypes->RemoveAll(true); + delete pColumnTypes; + pColumnTypes = null; + } + + if (pColumnValues != null) + { + pColumnValues->RemoveAll(true); + delete pColumnValues; + pColumnValues = null; + } + + } + + return r; +} + +result +HomePresentationModel::NotifyInstallationEvent(const PackageId& packageId) +{ + result r = E_SUCCESS; + String replace(APP_ID_REPLACE_STR); + String tempPackageId(packageId); + ArrayList* pNewAppList = null; + Integer* pNewKey = null; + HomeItemInfo* pItemInfo = null; + bool isalreadyExist = false; + int indexOf = 0; + r = tempPackageId.LastIndexOf(replace, 0, indexOf); + + if (!IsFailed(r) && indexOf) + { + tempPackageId.Remove(0, replace.GetLength()); + } + + if (__pPackMgr == null) + { + __pPackMgr = PackageManager::GetInstance(); + } + + if (__pPackMgr != null) + { + PackageInfo* pPackInfo = __pPackMgr->GetPackageInfoN(packageId); + + if (pPackInfo != null) + { + IList* pAppsInPack = pPackInfo->GetPackageAppInfoListN(); + + if (pAppsInPack != null) + { + IEnumerator* pPackageAppInfoEnum = pAppsInPack->GetEnumeratorN(); + + while (pPackageAppInfoEnum != null && pPackageAppInfoEnum->MoveNext() == E_SUCCESS) + { + ArrayList* pAppsList = null; + bool foundPosition = false; + IList* pKeysList = __pAppHashMap->GetKeysN(); + PackageAppInfo* pPackageAppInfo = static_cast(pPackageAppInfoEnum->GetCurrent()); + + if (pKeysList != null && pPackageAppInfo) + { + for (int keysCount = (pKeysList->GetCount() - 1); keysCount >= 0; keysCount--) + { + pItemInfo = FindAppObjectInList(tempPackageId); + + if (pItemInfo != null) + { + pItemInfo->Initialize(pPackageAppInfo, pPackInfo); + pItemInfo->SetApplicationIcon(null); + isalreadyExist = true; + foundPosition = true; + break; + } + } + + if (!isalreadyExist) + { + for (int keysCount = (pKeysList->GetCount() - 1); keysCount >= 0; keysCount--) + { + pAppsList = static_cast(__pAppHashMap->GetValue(*static_cast(pKeysList->GetAt(keysCount)))); + + if (pAppsList != null) + { + if (pAppsList->GetCount() < MAX_ICONS_PER_PAGE) + { + pItemInfo = new (std::nothrow) HomeItemInfo(); + + if (pItemInfo != null) + { + if (pItemInfo->Initialize(pPackageAppInfo, pPackInfo) == E_SUCCESS) + { + if (pItemInfo->IsVisibleInMainMenu()) + { + __totalApps++; + pItemInfo->SetPositionInHomeScreen(keysCount + 1, pAppsList->GetCount()); + pAppsList->Add(pItemInfo); + foundPosition = true; + break; + } + else + { + continue; + } + + } + else + { + delete pItemInfo; + pItemInfo = null; + } + } + } + } + } + } + + if (!foundPosition) + { + pNewAppList = new (std::nothrow) ArrayList(); + + if (pNewAppList != null) + { + r = pNewAppList->Construct(); + + if (pItemInfo == null) + { + pItemInfo = new (std::nothrow) HomeItemInfo(); + r = pItemInfo->Initialize(pPackageAppInfo, pPackInfo); + TryCatch(r == E_SUCCESS, , "failed to construct pNewAppList %s", + GetErrorMessage(r)); + } + if (pItemInfo->IsVisibleInMainMenu()) + { + __totalApps++; + __totalPages++; + pItemInfo->SetPositionInHomeScreen(__totalPages, 0); + r = pNewAppList->Add(pItemInfo); + TryCatch(r == E_SUCCESS, , "failed to construct pNewAppList %s", + GetErrorMessage(r)); + pNewKey = new (std::nothrow) Integer(__totalPages); + r = __pAppHashMap->Add(pNewKey, pNewAppList); + TryCatch(r == E_SUCCESS, , "failed to construct pNewAppList %s", + GetErrorMessage(r)); + } + } + } + } + if (pKeysList != null) + { + pKeysList->RemoveAll(); + delete pKeysList; + pKeysList = null; + } + } + if (pPackageAppInfoEnum != null) + { + delete pPackageAppInfoEnum; + pPackageAppInfoEnum = null; + } + if (pAppsInPack != null) + { + delete pAppsInPack; + pAppsInPack = null; + } + } + + delete pPackInfo; + pPackInfo = null; + } + else + { + r = E_SUCCESS; + } + } + else + { + r = GetLastResult(); + } + + if (__pDataListener != null && pItemInfo != null) + { + __pDataListener->OnInstallationCompleted(*pItemInfo /*, isalreadyExist*/); + } + + return r; + +CATCH: + + if (pItemInfo != null) + { + delete pItemInfo; + pItemInfo = null; + } + + if (pNewAppList != null) + { + delete pNewAppList; + pNewAppList = null; + } + + if (pNewKey != null) + { + delete pNewKey; + pNewKey = null; + } + + return r; +} + +result +HomePresentationModel::PrepareApplicationsList(void) +{ + result r = E_SUCCESS; + r = UpdateWithPositions(); + SortPages(); + return r; +} + +void +HomePresentationModel::SortPages(void) +{ + if (__pAppHashMap != null) + { + IList* pKeys = null; + ArrayList* pValues = null; + IEnumerator* pKeysEnum = null; + + pKeys = __pAppHashMap->GetKeysN(); + + if (pKeys != null) + { + pKeysEnum = pKeys->GetEnumeratorN(); + + if (pKeysEnum != null) + { + while (pKeysEnum != null && pKeysEnum->MoveNext() == E_SUCCESS) + { + Integer* pKeyName = static_cast(pKeysEnum->GetCurrent()); + pValues = static_cast(__pAppHashMap->GetValue(*pKeyName)); + + if (pValues != null) + { + pValues->Sort(__comparerObject); + UpdatePositions(*pValues); + } + } + } + + if (pKeysEnum != null) + { + delete pKeysEnum; + pKeysEnum = null; + } + + pKeys->RemoveAll(false); + delete pKeys; + pKeys = null; + } + } +} + +result +HomePresentationModel::UpdateDataToDatabase(HomeItemInfo* pItemInfo) +{ + result r = E_INVALID_ARG; + + if (pItemInfo != null) + { + ArrayList* pColumnNames = null; + ArrayList* pColumnTypes = null; + ArrayList* pColumnValues = null; + String* whereCondition = null; + String* pTempString = null; + Integer* pTempInt = null; + int pageNumber = 0; + int pageIndex = 0; + + //Constructing various array list + pColumnNames = new (std::nothrow) ArrayList(); + pColumnNames->Construct(); + pColumnTypes = new (std::nothrow) ArrayList(); + pColumnTypes->Construct(); + pColumnValues = new (std::nothrow) ArrayList(); + pColumnValues->Construct(); + + pItemInfo->GetPositionInHomeScreen(pageNumber, pageIndex); + + //Application pageNumber + pTempString = new (std::nothrow) String(APPS_APP_PAGE); + r = pColumnNames->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(DB_COLUMNTYPE_INT); + r = pColumnTypes->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnTypes->Add(pTempInt); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(pageNumber); + r = pColumnValues->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnValues->Add(pTempInt); failed %s", GetErrorMessage(r)); + //Application pageIndex + pTempString = new (std::nothrow) String(APPS_APP_PAGEINDEX); + r = pColumnNames->Add(pTempString); + TryCatch(r == E_SUCCESS, delete pTempString; + pTempString = null, + "pColumnNames->Add(pTempString); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(DB_COLUMNTYPE_INT); + r = pColumnTypes->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnTypes->Add(pTempInt); failed %s", GetErrorMessage(r)); + pTempInt = new (std::nothrow) Integer(pageIndex); + r = pColumnValues->Add(pTempInt); + TryCatch(r == E_SUCCESS, delete pTempInt; + pTempInt = null, + "pColumnValues->Add(pTempInt); failed %s", GetErrorMessage(r)); + + //update + whereCondition = new (std::nothrow) String(APPS_APP_ID); + whereCondition->Append(L" = "); + whereCondition->Append(L'\"'); + whereCondition->Append(pItemInfo->GetAppId()); + whereCondition->Append(L'\"'); + + r = __pDataBaseManager->UpdateTable(HOME_APPLICATIONS_TABLE, pColumnNames, pColumnTypes, pColumnValues, whereCondition); + +CATCH: + + if (pColumnNames != null) + { + pColumnNames->RemoveAll(true); + delete pColumnNames; + pColumnNames = null; + } + + if (pColumnTypes != null) + { + pColumnTypes->RemoveAll(true); + delete pColumnTypes; + pColumnTypes = null; + } + + if (pColumnValues != null) + { + pColumnValues->RemoveAll(true); + delete pColumnValues; + pColumnValues = null; + } + + if (whereCondition) + { + delete whereCondition; + whereCondition = null; + } + + } + + return r; +} + +void +HomePresentationModel::UpdatePositions(Tizen::Base::Collection::ArrayList& pAppListToUpdate) +{ + for (int appIndex = 0; appIndex < pAppListToUpdate.GetCount(); appIndex++) + { + HomeItemInfo* pItemInfo = static_cast(pAppListToUpdate.GetAt(appIndex)); + pItemInfo->SetItemIndex(appIndex); + } + + pAppListToUpdate.Sort(__comparerObject); +} + +result +HomePresentationModel::UpdateWithPositions(void) +{ + result r = E_INVALID_STATE; + //Sanity test + if (__pDataBaseManager == null) + { + r = InitializeDatabase(); + + if (IsFailed(r)) + { + AppLogException("Home_Exception::InitializeDataBase() failed with error = %s", GetErrorMessage(r)); + return r; + } + } + + if (__pAppHashMap != null) + { + IList* pKeys = null; + ArrayList* pValues = null; + IEnumerator* pKeysEnum = null; + + pKeys = __pAppHashMap->GetKeysN(); + + if (pKeys != null) + { + pKeysEnum = pKeys->GetEnumeratorN(); + + if (pKeysEnum != null) + { + while (pKeysEnum != null && pKeysEnum->MoveNext() == E_SUCCESS) + { + Integer* pKeyName = static_cast(pKeysEnum->GetCurrent()); + pValues = static_cast(__pAppHashMap->GetValue(*pKeyName)); + + if (pValues != null) + { + + for (int appCount = 0; appCount < pValues->GetCount(); appCount++) + { + HomeItemInfo* pItemInfo = dynamic_cast(pValues->GetAt(appCount)); + + if (pItemInfo != null) + { + String whereState(APPS_APP_ID); + String appId = pItemInfo->GetAppId(); + HashMap* pRowData = new (std::nothrow) HashMap(); + whereState.Append(L" = "); + whereState.Append(L'\"'); + whereState.Append(appId); + whereState.Append(L'\"'); + pRowData->Construct(); + r = __pDataBaseManager->GetDataRowFromTable(HOME_APPLICATIONS_TABLE, whereState, *pRowData); + + if (!IsFailed(r) && pRowData->GetCount()) + { + + Integer* pPageIndex = null; + Integer* pPageNumber = static_cast(pRowData->GetValue(String(APPS_APP_PAGE))); + pPageIndex = static_cast(pRowData->GetValue(String(APPS_APP_PAGEINDEX))); + + if (pPageNumber != null && pPageIndex != null) + { + pItemInfo->SetPositionInHomeScreen(pPageNumber->ToInt(), pPageIndex->ToInt()); + } + + } + else + { + r = InsertPageDataInDataBase(pItemInfo); + r = E_SUCCESS; + } + + if (pRowData != null) + { + pRowData->RemoveAll(true); + delete pRowData; + pRowData = null; + } + } + } + } + } + } + //CATCH: + if (pKeysEnum != null) + { + delete pKeysEnum; + pKeysEnum = null; + } + + pKeys->RemoveAll(false); + delete pKeys; + pKeys = null; + } + } + + return r; + +} diff --git a/src/HmMainFrame.cpp b/src/HmMainFrame.cpp new file mode 100644 index 0000000..ca4dd90 --- /dev/null +++ b/src/HmMainFrame.cpp @@ -0,0 +1,48 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmMainFrame.cpp + * @brief Keeps implementation of Main Frame for the application + */ + +#include "HmMainFrame.h" + +using namespace Tizen::Base; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; + +MainFrame::MainFrame(void) +{ + //No implementation needed +} + +MainFrame::~MainFrame(void) +{ + //No implementation needed +} + +result +MainFrame::OnInitializing(void) +{ + return E_SUCCESS; +} + +result +MainFrame::OnTerminating(void) +{ + return E_SUCCESS; +} diff --git a/src/HmPackageInfoListRetrieveThread.cpp b/src/HmPackageInfoListRetrieveThread.cpp new file mode 100644 index 0000000..05d974c --- /dev/null +++ b/src/HmPackageInfoListRetrieveThread.cpp @@ -0,0 +1,241 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file PackageInfoListRetrieveThread.h + * @brief The file contains declaration of PackageInfoListRetrieveThread, + * which is a worker thread and being used to retrieve the list PackageInfos, for the Applications installed on device. + */ + +#include +#include "HmHomeItemInfo.h" +#include "HmPackageInfoListRetrieveThread.h" +#include "HmTypes.h" + +using namespace Tizen::App; +using namespace Tizen::App::Package; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; + +PackageInfoListRetrieveThread::PackageInfoListRetrieveThread(IPackageInfoListListener* pPackageListener) + : __pPackageListener(pPackageListener) +{ + // No implementation required + +} + +PackageInfoListRetrieveThread::~PackageInfoListRetrieveThread(void) +{ + // No implementation required +} + +result +PackageInfoListRetrieveThread::SetPackageType(void) +{ + return Start(); +} + +Object* +PackageInfoListRetrieveThread::Run(void) +{ + result r = E_SUCCESS; + PackageManager* pPackMgr = PackageManager::GetInstance(); + String currentAppName = UiApp::GetInstance()->GetAppName(); + int currentPage = 1; + int currentPosition = 0; + int totalApps = 0; + int totalPages = 0; + HashMap* pAppHashMap = null; + IList* pPackList = null; + IEnumerator* pEnum = null; + + if (pAppHashMap == null) + { + ArrayList* pArrayList = null; + Integer* pKey = null; + // constructs hashmap to maintain key(page number) value(list of icons associated to the page) pairs of all pages + pAppHashMap = new (std::nothrow) HashMap(); + r = pAppHashMap->Construct(); + pArrayList = new (std::nothrow) ArrayList(); + r = pArrayList->Construct(); + pKey = new (std::nothrow) Integer(currentPage); + r = pAppHashMap->Add(pKey, pArrayList); //transfers ownership to the hashmap + TryCatch(r == E_SUCCESS, delete pKey; + pKey = null; + delete pArrayList; + pArrayList = null, "pAppHashMap->Add(*pKey, *pArrayList) failed with error = %s", GetErrorMessage(r)); + + } + + if (pPackMgr != null) + { + pPackList = pPackMgr->GetPackageInfoListN(); + + if (pPackList == null) + { + __pPackageListener->OnPackageInfoRetrievedN(pAppHashMap, totalApps, totalPages); + return null; + } + + pEnum = pPackList->GetEnumeratorN(); + + while (pEnum != null && pEnum->MoveNext() == E_SUCCESS) + { +// PackageType type = PACKAGE_TYPE_TPK; + HomeItemInfo* pItemInfo = null; + ArrayList* pAppsList = null; + IList* pPackAppInfoList = null; + IEnumerator* pAppInfoEnumerator = null; + PackageInfo* pInfo = static_cast(pEnum->GetCurrent()); + TryCatch(pInfo != null, r = GetLastResult(), "pInfo is null error %s", GetErrorMessage(GetLastResult())); + pPackAppInfoList = pInfo->GetPackageAppInfoListN(); + + if (pPackAppInfoList != null) + { + pAppInfoEnumerator = pPackAppInfoList->GetEnumeratorN(); + + while (pAppInfoEnumerator != null && pAppInfoEnumerator->MoveNext() == E_SUCCESS) + { + PackageAppInfo* pPackAppInfo = static_cast(pAppInfoEnumerator->GetCurrent()); + pAppsList = static_cast(pAppHashMap->GetValue(Integer(currentPage))); + TryCatch(pAppsList != null, r = GetLastResult(), "pInfo is null error %s", GetErrorMessage(GetLastResult())); + // creates an instance of HomeItemInfo for each application to store the details of the application. + pItemInfo = new (std::nothrow) HomeItemInfo(); + r = pItemInfo->Initialize(pPackAppInfo, pInfo); + + if (!pItemInfo->IsVisibleInMainMenu() || pItemInfo->GetIconPath().IsEmpty()) + { + delete pItemInfo; + pItemInfo = null; + continue; + } + totalApps++; + pItemInfo->SetPositionInHomeScreen(currentPage, currentPosition); + + // adds to the list if not service application + // if (!pItemInfo->GetAppName().Contains(L"service") + // && !pItemInfo->GetAppName().Equals(currentAppName, true)) + { + currentPosition++; + r = pAppsList->Add(pItemInfo); + + if (IsFailed(r)) + { + AppLogException("Failed to pAppsList->Add(pItemInfo) error %s", GetErrorMessage(r)); + delete pItemInfo; + pItemInfo = null; + continue; + } + + if (currentPosition >= MAX_ICONS_PER_PAGE) + { + currentPage++; + currentPosition = 0; + ArrayList* pArrayList = new (std::nothrow) ArrayList(); + pArrayList->Construct(); + Integer* pKey = new (std::nothrow) Integer(currentPage); + pAppHashMap->Add(pKey, pArrayList); //transfers ownership to the hashmap + } + } + // else + // { + // delete pItemInfo; + // pItemInfo = null; + // } + } + if (pAppInfoEnumerator != null) + { + delete pAppInfoEnumerator; + pAppInfoEnumerator = null; + } + } + + pPackAppInfoList->RemoveAll(); + delete pPackAppInfoList; + pPackAppInfoList = null; + } + + if (currentPosition == 0 && currentPage > 1) + { + pAppHashMap->Remove(Integer(currentPage), true); + totalPages = currentPage - 1; + } + else + { + totalPages = currentPage; + } + + __pPackageListener->OnPackageInfoRetrievedN(pAppHashMap, totalApps, totalPages); + pAppHashMap = null; //ownership transferred to the caller + + if (pEnum != null) + { + delete pEnum; + pEnum = null; + } + + if (pPackList != null) + { + pPackList->RemoveAll(true); + delete pPackList; + pPackList = null; + } + } + + return null; + +CATCH: + + if (pEnum != null) + { + delete pEnum; + pEnum = null; + } + + if (pPackList != null) + { + pPackList->RemoveAll(true); + delete pPackList; + pPackList = null; + } + + if (pAppHashMap != null) + { + if (pAppHashMap->GetCount() > 0) + { + IList* pKeysList = pAppHashMap->GetKeysN(); + + for (int keyCount = 0; keyCount < pKeysList->GetCount(); keyCount++) + { + ArrayList* pAppList = static_cast(pAppHashMap->GetValue(*static_cast(pKeysList->GetAt(keyCount)))); + + if (pAppList != null) + { + pAppList->RemoveAll(true); + } + } + + pKeysList->RemoveAll(); + delete pKeysList; + } + + pAppHashMap->RemoveAll(true); + delete pAppHashMap; + pAppHashMap = null; + } + + return null; +} diff --git a/src/HmProgressPanel.cpp b/src/HmProgressPanel.cpp new file mode 100644 index 0000000..38da4b0 --- /dev/null +++ b/src/HmProgressPanel.cpp @@ -0,0 +1,215 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmProgressPanel.cpp + * @brief Keeps implementation of ProgressPanel Implementation + */ +#include +#include +#include +#include +#include "HmApplicationUtils.h" +#include "HmProgressPanel.h" +#include "HmTypes.h" + +using namespace Tizen::App; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Graphics; +using namespace Tizen::Media; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Animations; +using namespace Tizen::Ui::Controls; + +ProgressPanel::ProgressPanel(void) + : __pAnimationFrameList(null) + , __pAnimation(null) +{ + +} +ProgressPanel::~ProgressPanel(void) +{ + if (__pAnimationFrameList != null) + { + __pAnimationFrameList->RemoveAll(true); + delete __pAnimationFrameList; + } +} + +result +ProgressPanel::Construct(const Tizen::Graphics::Rectangle& controlRectangle) +{ + result r = E_SUCCESS; + long duration = DURATION_FOR_EACH_IMAGE / MAX_BITMAP_COUNT; + r = Panel::Construct(controlRectangle); + TryCatch(r == E_SUCCESS, , "Panel::Construct failed with error = %s", GetErrorMessage(r)); + __pAnimationFrameList = new (std::nothrow) ArrayList(); + __pAnimationFrameList->Construct(); + + // Create Bitmaps + for (int bmpCount = 0; bmpCount < MAX_BITMAP_COUNT; bmpCount++) + { + Bitmap* pProgressBitmap = null; + String bitmapName(WAIT_CURSOR_IMAGE_BASE); + bitmapName.Append(bmpCount); + bitmapName.Append(BITMAP_EXTENSION); + + pProgressBitmap = ApplicationUtils::GetResourceBitmapN(bitmapName); + + if (pProgressBitmap != null) + { + AnimationFrame* pProgressAniFrame = new (std::nothrow) AnimationFrame(*pProgressBitmap, duration); + + if (pProgressAniFrame != null) + { + r = __pAnimationFrameList->Add(pProgressAniFrame); + + if (IsFailed(r)) + { + delete pProgressAniFrame; + pProgressAniFrame = null; + } + } + + delete pProgressBitmap; + pProgressBitmap = null; + } + } + + // Create Animation + __pAnimation = new (std::nothrow) Animation(); + r = __pAnimation->Construct(Rectangle((controlRectangle.width / 2 - WAIT_CURSUR_DIMESION / 2), (controlRectangle.height / 2 - WAIT_CURSUR_DIMESION / 2), + WAIT_CURSUR_DIMESION, WAIT_CURSUR_DIMESION), *__pAnimationFrameList); + TryCatch(r == E_SUCCESS, , "__pAnimation->Construct failed with error = %s", GetErrorMessage(r)); + __pAnimation->SetRepeatCount(REPEAT_COUNT); + r = AddControl(*__pAnimation); + TryCatch(r == E_SUCCESS, , "AddControl(*__pAnimation) failed with error = %s", GetErrorMessage(r)); + + return r; + +CATCH: + + if (__pAnimation != null) + { + delete __pAnimation; + __pAnimation = null; + } + + if (__pAnimationFrameList) + { + __pAnimationFrameList->RemoveAll(true); + delete __pAnimationFrameList; + __pAnimationFrameList = null; + } + + return r; +} + +result +ProgressPanel::StartAnimation(void) +{ + + result r = E_SUCCESS; + bool animatorFailed = false; + ControlAnimator* pAniControlAnimator = null; + + TryReturn(__pAnimation != null, E_INVALID_STATE, "Animation is not yet constructed"); + + pAniControlAnimator = __pAnimation->GetControlAnimator(); + + if (pAniControlAnimator != null) + { + if (pAniControlAnimator->GetStatus() == ANIMATOR_STATUS_PLAYING) + { + r = pAniControlAnimator->StopAllAnimations(); + } + + if (r == E_SUCCESS) + { + r = pAniControlAnimator->SetShowState(true); + + if (IsFailed(r)) + { + animatorFailed = true; + } + } + else + { + animatorFailed = true; + } + + if (animatorFailed) + { + r = __pAnimation->SetShowState(true); + } + + __pAnimation->Play(); + RequestRedraw(true); + } + else + { + return E_FAILURE; + } + return r; +} + +result +ProgressPanel::StopAnimation(void) +{ + + result r = E_SUCCESS; + bool animatorFailed = false; + ControlAnimator* pAniControlAnimator = null; + + TryReturn(__pAnimation != null, E_INVALID_STATE, "Animation is not yet constructed"); + pAniControlAnimator = __pAnimation->GetControlAnimator(); + + if (pAniControlAnimator != null) + { + if (pAniControlAnimator->GetStatus() == ANIMATOR_STATUS_PLAYING) + { + r = pAniControlAnimator->StopAllAnimations(); + } + + if (r == E_SUCCESS) + { + r = pAniControlAnimator->SetShowState(false); + + if (IsFailed(r)) + { + animatorFailed = true; + } + } + else + { + animatorFailed = true; + } + + if (animatorFailed) + { + r = __pAnimation->SetShowState(false); + } + + __pAnimation->Stop(); + } + else + { + r = E_FAILURE; + } + + return r; +} diff --git a/src/HmTypes.cpp b/src/HmTypes.cpp new file mode 100644 index 0000000..fb73f0f --- /dev/null +++ b/src/HmTypes.cpp @@ -0,0 +1,104 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file HmTypes.cpp + * @brief Keeps all the constants definitions, used throughout the application + */ + +#include +#include "HmTypes.h" + +using namespace Tizen::Graphics; + +const wchar_t* IDB_BACKGROUND_IMAGE = L"BG.png"; +const wchar_t* IDB_CLOSE_ICON = L"Menu_Btn_Uninstall.png"; +const wchar_t* IDB_SELECTED_BUBBLE_TOP = L"Page_indicator_0"; +const wchar_t* IDB_BUBBLE_TOP = L"Page_indicator_002.png"; +const wchar_t* IDB_SETTING_BUTTON = L"Menu_Btn_setting.png"; +const wchar_t* IDB_SETTING_BUTTON_PRESSED = L"Menu_Btn_setting_press.png"; +const wchar_t* SETTINGS_KEY_WALLPAPER = L"http://tizen.org/setting/screen.wallpaper"; +const wchar_t* SETTINGS_KEY_LANGUAGE = L"http://tizen.org/setting/locale.language"; +const wchar_t* WAIT_CURSOR_IMAGE_BASE = L"progressing0"; +const wchar_t* BITMAP_EXTENSION = L".png"; +const wchar_t* IDB_DEFAULT_APP_ICON = L"default_app_icon.png"; +const wchar_t* APP_ID_REPLACE_STR = L"org.tizen."; +const wchar_t* SETTING_ANIMATION_PROPERTY_NAME = L"Opacity"; +const wchar_t* HOME_DATABASE_NAME = L"data/HomeDB.db"; +const wchar_t* HOME_APPLICATIONS_TABLE = L"homeapps"; +const wchar_t* APPS_RECORD_ID = L"appRecordID"; +const wchar_t* APPS_APP_ID = L"appId"; +const wchar_t* APPS_APP_NAME = L"appName"; +const wchar_t* APPS_APP_ICON = L"appIconPath"; +const wchar_t* APPS_APP_PAGE = L"pageNumber"; +const wchar_t* APPS_APP_PAGEINDEX = L"iconIndex"; +//DATATYPES +const wchar_t* DATATYPE_INTEGER_PRIMARY = L"INTEGER PRIMARY KEY"; +const wchar_t* DATATYPE_INTEGER = L"INTEGER"; +const wchar_t* DATATYPE_TEXT = L"TEXT"; +const wchar_t* DATATYPE_UNIQUE = L" UNIQUE"; +const wchar_t* CREATE_TABLE = L"CREATE TABLE IF NOT EXISTS "; +const wchar_t* INSERT_TABLE = L"INSERT INTO "; +const wchar_t* SELECT_TABLE = L"SELECT * FROM "; +const wchar_t* DELETE_TABLE = L"DELETE FROM "; +const wchar_t* UPDATE_TABLE = L"UPDATE "; +const wchar_t* GET_LAST_RECORD_ID = L"SELECT last_insert_rowid() FROM "; + +const unsigned int COLOR_SETTING_BOUNDARY_INNER = Color32<44, 44, 44>::Value; + +const int X_MARKER_LABEL_OFFSET = 10; +const int X_MARKER_POSITION = 156; +const int Y_MARKER_POSITION = 42; +const int W_MARKER_LABEL = 34; +const int H_MARKER_LABEL = 34; +const int W_MARKER_OFFSET = 130; +const int W_APPLICATION_ICON = 170; +const int H_APPLICATION_ICON = 212; +const int X_PAGE_POSITION = 0; +const int X_PAGE_OFFSET = 20; +const int H_EDIT = 60; +const int H_CONTROL_OFFSET = 10; +const int H_APP_CAPTION_TEXT = 68; +const int Y_APP_ICON_IMAGE_START = 24; +const int H_PAGE_MARKER = 104; +const int W_DEFAULT_PAGE = 720; +const int X_SETTING_PANEL = 6; +const int Y_SETTING_PANEL = 42; +const int W_SETTING_PANEL = 138; +const int H_SETTING_PANEL = 48; +const int X_SETTING_PANEL_PRESSED_OFFSET = 14; +const int SIZE_SETTING_LABEL_OFFSET = 2; +const int GAP_ICON_HORIZONTAL = 0; +const int GAP_ICON_VERTICAL = 0; +const int OVERLAY_BITMAP_DIMENSION = 60; +const int WAIT_CURSUR_DIMESION = 96; +const int APP_ICON_IMAGE_SIZE = 96; +const int DURATION_FOR_EACH_IMAGE = 500; +const int DURATION_SETTING_ANIMATION = 500; +const int LONG_TOUCH_GESTURE_DURATION = 300; //miliseconds +const int MOVEMENT_UPDATE_DURATION = 2000; +const int SCROLL_ANIMATION_DURATION = 20; +const int FONT_SIZE_APP_CAPTION = 23; +const unsigned int COLOR_APP_ICON_CAPTION = Color32<249, 249, 249>::Value; +const unsigned int COLOR_APP_CAPTION_SHADOW1 = Color32<100, 100, 100>::Value; +const unsigned int COLOR_APP_CAPTION_SHADOW2 = Color32<40, 40, 40>::Value; +const int IDA_OVERLAYBITMAP_CLOSE = 100; +const int IDA_SETTING_BUTTON = 101; +const int MAX_ICONS_PER_PAGE = 20; +const int MAX_PAGE_COUNT = 9; +const int MAX_BITMAP_COUNT = 8; +const int REPEAT_COUNT = 10000; +const int MOVING_ICON_OPACITY = 120; -- 2.7.4