diff --git a/bbmcontacts/.cproject b/bbmcontacts/.cproject new file mode 100644 index 00000000..386bb327 --- /dev/null +++ b/bbmcontacts/.cproject @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bbmcontacts/.device b/bbmcontacts/.device new file mode 100644 index 00000000..0d17d2a7 --- /dev/null +++ b/bbmcontacts/.device @@ -0,0 +1,6 @@ +#Project target device definition. +#Mon Jun 03 14:24:11 EDT 2013 +ppi=356 +height=1280 +kind=PHONE +width=768 diff --git a/bbmcontacts/.project b/bbmcontacts/.project new file mode 100644 index 00000000..2aa88b3b --- /dev/null +++ b/bbmcontacts/.project @@ -0,0 +1,96 @@ + + + bbmcontacts + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + Device-Debug + + + org.eclipse.cdt.make.core.buildArguments + -j8 + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + true + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + Device-Debug + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + com.rim.tad.tools.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + com.rim.tad.tools.qml.core.qmlFileBuilder + + + + + com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder + + + + + + com.rim.tad.tools.wst.jsdt.core.jsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.qnx.tools.ide.bbt.core.bbtnature + org.eclipse.cdt.core.ccnature + com.rim.tad.tools.qml.core.qmlNature + + diff --git a/bbmcontacts/.settings/com.rim.tad.tools.wst.jsdt.ui.superType.container b/bbmcontacts/.settings/com.rim.tad.tools.wst.jsdt.ui.superType.container new file mode 100644 index 00000000..e2306136 --- /dev/null +++ b/bbmcontacts/.settings/com.rim.tad.tools.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +com.rim.tad.tools.wst.jsdt.launching.JRE_CONTAINER \ No newline at end of file diff --git a/bbmcontacts/.settings/com.rim.tad.tools.wst.jsdt.ui.superType.name b/bbmcontacts/.settings/com.rim.tad.tools.wst.jsdt.ui.superType.name new file mode 100644 index 00000000..11006e2a --- /dev/null +++ b/bbmcontacts/.settings/com.rim.tad.tools.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Global \ No newline at end of file diff --git a/bbmcontacts/.settings/org.eclipse.cdt.core.prefs b/bbmcontacts/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 00000000..f5810250 --- /dev/null +++ b/bbmcontacts/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,33 @@ +eclipse.preferences.version=1 +environment/project/com.qnx.qcc.toolChain.1606140832/CPULIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1606140832/CPULIST/operation=append +environment/project/com.qnx.qcc.toolChain.1606140832/CPULIST/value=arm +environment/project/com.qnx.qcc.toolChain.1606140832/VARIANTLIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1606140832/VARIANTLIST/operation=append +environment/project/com.qnx.qcc.toolChain.1606140832/VARIANTLIST/value=g +environment/project/com.qnx.qcc.toolChain.1606140832/append=true +environment/project/com.qnx.qcc.toolChain.1606140832/appendContributed=true +environment/project/com.qnx.qcc.toolChain.1653367009/CPULIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1653367009/CPULIST/operation=append +environment/project/com.qnx.qcc.toolChain.1653367009/CPULIST/value=arm +environment/project/com.qnx.qcc.toolChain.1653367009/EXCLUDE_VARIANTLIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1653367009/EXCLUDE_VARIANTLIST/operation=append +environment/project/com.qnx.qcc.toolChain.1653367009/EXCLUDE_VARIANTLIST/value=p +environment/project/com.qnx.qcc.toolChain.1653367009/append=true +environment/project/com.qnx.qcc.toolChain.1653367009/appendContributed=true +environment/project/com.qnx.qcc.toolChain.1740526165/CPULIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1740526165/CPULIST/operation=append +environment/project/com.qnx.qcc.toolChain.1740526165/CPULIST/value=arm +environment/project/com.qnx.qcc.toolChain.1740526165/EXCLUDE_VARIANTLIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1740526165/EXCLUDE_VARIANTLIST/operation=append +environment/project/com.qnx.qcc.toolChain.1740526165/EXCLUDE_VARIANTLIST/value=r +environment/project/com.qnx.qcc.toolChain.1740526165/append=true +environment/project/com.qnx.qcc.toolChain.1740526165/appendContributed=true +environment/project/com.qnx.qcc.toolChain.505646349/CPULIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.505646349/CPULIST/operation=append +environment/project/com.qnx.qcc.toolChain.505646349/CPULIST/value=x86 +environment/project/com.qnx.qcc.toolChain.505646349/VARIANTLIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.505646349/VARIANTLIST/operation=append +environment/project/com.qnx.qcc.toolChain.505646349/VARIANTLIST/value=g +environment/project/com.qnx.qcc.toolChain.505646349/append=true +environment/project/com.qnx.qcc.toolChain.505646349/appendContributed=true diff --git a/bbmcontacts/LICENSE b/bbmcontacts/LICENSE new file mode 100644 index 00000000..7ef1c23e --- /dev/null +++ b/bbmcontacts/LICENSE @@ -0,0 +1,176 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + 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. + + 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, + 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 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 in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) 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 + + (d) 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 \ No newline at end of file diff --git a/bbmcontacts/Makefile b/bbmcontacts/Makefile new file mode 100644 index 00000000..925f4b44 --- /dev/null +++ b/bbmcontacts/Makefile @@ -0,0 +1,6 @@ +QMAKE_TARGET = bbmcontacts +PROJECT_DIR := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))) +I18N_DIR := $(PROJECT_DIR)/translations + +include mk/cs-base.mk + diff --git a/bbmcontacts/assets/720x720/ContactScrollView.qml b/bbmcontacts/assets/720x720/ContactScrollView.qml new file mode 100644 index 00000000..b4bbbf13 --- /dev/null +++ b/bbmcontacts/assets/720x720/ContactScrollView.qml @@ -0,0 +1,24 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ +import bb.cascades 1.0 + +// For the 720x720 resolution a ScrollView is used, for the standard +// resolution this would lead to rubberbanding of a full screen UI +// which we do not want (see assets/BbmProfileScrollView.qml) +ScrollView { + scrollViewProperties { + scrollMode: ScrollMode.Vertical + } +} \ No newline at end of file diff --git a/bbmcontacts/assets/ContactItem.qml b/bbmcontacts/assets/ContactItem.qml new file mode 100644 index 00000000..ded76da5 --- /dev/null +++ b/bbmcontacts/assets/ContactItem.qml @@ -0,0 +1,77 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import bb.cascades 1.0 +//! [0] +// Container that represents a Contact in the ListView +Container { + + topPadding: 40 + leftPadding: 40 + rightPadding: 40 + + Container { + Container { + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + + Container { + layoutProperties: StackLayoutProperties { + spaceQuota: 1 + } + // Contacts display name + Label { + verticalAlignment: VerticalAlignment.Center + + text: ListItemData.displayName + textStyle { + color: Color.White + } + } + // Contacts personal message + Label { + verticalAlignment: VerticalAlignment.Center + leftMargin: 50.0 + + multiline: true + + text: ListItemData.personalMessage + textStyle { + color: Color.White + fontSize: FontSize.Small + } + + } + } + // The Contacts display image + ImageView { + verticalAlignment: VerticalAlignment.Center + + image: ListItemData.avatar + scalingMethod: ScalingMethod.None + preferredHeight: 100 + preferredWidth: 100 + } + } + Container { + background: Color.White + + Divider { + } + } + } +} +//! [0] \ No newline at end of file diff --git a/bbmcontacts/assets/ContactList.qml b/bbmcontacts/assets/ContactList.qml new file mode 100644 index 00000000..50469f25 --- /dev/null +++ b/bbmcontacts/assets/ContactList.qml @@ -0,0 +1,77 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import bb.cascades 1.0 + +// The main page displaying the number of contacts that have +// this application installed and a list of the contacts. +NavigationPane { + id: navigationPane + + onPopTransitionEnded: page.destroy() + + Page { + Container { + + layout: DockLayout { + } + // app background image + ImageView { + horizontalAlignment: HorizontalAlignment.Fill + verticalAlignment: VerticalAlignment.Fill + + imageSource: "asset:///images/background_blurred.png" + } + + Container { + // Custom component indicating number of contacts + //! [0] + Field { + id: contactCount + objectName: "contactCount" + title: qsTr("BBM Contacts") + value: "0" + } + //! [0] + //! [1] + // The list of contacts + ListView { + objectName: "contactListView" + + listItemComponents: [ + ListItemComponent { + ContactItem { + } + } + ] + // Create Contact page upon the user selecting a contact from the list + onTriggered: { + //This gives the selected contact. + var page = contactPage.createObject(); + page.contact = dataModel.data(indexPath); + navigationPane.push(page); + } + } + //! [1] + } + } + } + //! [2] + attachedObjects: ComponentDefinition { + id: contactPage + source: "ContactPage.qml" + } + //! [2] +} \ No newline at end of file diff --git a/bbmcontacts/assets/ContactPage.qml b/bbmcontacts/assets/ContactPage.qml new file mode 100644 index 00000000..31a718b8 --- /dev/null +++ b/bbmcontacts/assets/ContactPage.qml @@ -0,0 +1,127 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import bb.cascades 1.0 +import com.example.contact 1.0 + +// Page for displaying Contact details +Page { + + property Contact contact + + ContactScrollView { + Container { + + layout: DockLayout { + } + + ImageView { + horizontalAlignment: HorizontalAlignment.Fill + verticalAlignment: VerticalAlignment.Fill + + imageSource: "asset:///images/background_blurred.png" + } + + Container { + horizontalAlignment: HorizontalAlignment.Fill + verticalAlignment: VerticalAlignment.Fill + + topPadding: 20 + leftPadding: 20 + rightPadding: 20 + + // Container for Contact avatar image + Container { + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + //! [0] + ImageView { + preferredHeight: 300 + preferredWidth: 300 + + image: contact ? contact.avatar : null + } + //! [0] + } + + Divider { + } + + // Container to display Contact availability + Container { + minHeight: 50 + + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + //! [1] + ImageView { + verticalAlignment: VerticalAlignment.Center + + imageSource: "images/busy.png" + visible: contact ? contact.busy : false + } + + Label { + layoutProperties: StackLayoutProperties { + spaceQuota: 1 + } + + text: contact ? contact.displayName : "n/a" + textStyle { + color: Color.White + fontWeight: FontWeight.Bold + } + } + //! [1] + } + + // A set of custom fields to display contact details such as, + // display name, handle, etc. + //! [2] + Field { + title: qsTr("status message") + value: contact ? contact.statusMessage : "n/a" + } + //! [2] + Field { + title: qsTr("personal message") + value: contact ? contact.personalMessage : "n/a" + } + + Field { + title: qsTr("pp id") + value: contact ? contact.ppid : "n/a" + } + + Field { + title: qsTr("app version") + value: contact ? contact.appVersion : "n/a" + } + + Field { + title: qsTr("handle") + value: contact ? contact.handle : "n/a" + } + + Field { + title: qsTr("platform version") + value: contact ? contact.platformVersion : "n/a" + } + } + } + } +} diff --git a/bbmcontacts/assets/ContactScrollView.qml b/bbmcontacts/assets/ContactScrollView.qml new file mode 100644 index 00000000..e62b72de --- /dev/null +++ b/bbmcontacts/assets/ContactScrollView.qml @@ -0,0 +1,21 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ +import bb.cascades 1.0 + +// In the default resolution we do not add a scroll to the UI, since we do +// not want rubberbanding at the top and bottom. For a smaller screen this +// component will contain a vertical ScrollView (see assets/720x720/BbmProfileScrollView.qml) +Container { +} \ No newline at end of file diff --git a/bbmcontacts/assets/Field.qml b/bbmcontacts/assets/Field.qml new file mode 100644 index 00000000..98fbf09b --- /dev/null +++ b/bbmcontacts/assets/Field.qml @@ -0,0 +1,59 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import bb.cascades 1.0 + +// Custom component mimicking a labeled field +Container { + property alias title: titleField.text + property alias value: valueField.text + + topMargin: 10 + + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + + Label { + id: titleField + + layoutProperties: StackLayoutProperties { + spaceQuota: 1 + } + + textStyle { + base: SystemDefaults.TextStyles.BodyText + color: Color.White + fontStyle: FontStyle.Italic + } + + opacity: 0.7 + } + + Label { + id: valueField + + layoutProperties: StackLayoutProperties { + spaceQuota: 1 + } + + textStyle { + base: SystemDefaults.TextStyles.BodyText + color: Color.White + } + + multiline: true + } +} diff --git a/bbmcontacts/assets/Registration.qml b/bbmcontacts/assets/Registration.qml new file mode 100644 index 00000000..7f6c412d --- /dev/null +++ b/bbmcontacts/assets/Registration.qml @@ -0,0 +1,76 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import bb.cascades 1.0 + +// Page dealing with bbm registration +NavigationPane { + id: navigationPane + + Page { + id: page + + Container { + onCreationCompleted: { + navigationPane.push(page); + _registrationHandler.registerApplication(); + } + + layout: DockLayout { + } + + ImageView { + horizontalAlignment: HorizontalAlignment.Fill + verticalAlignment: VerticalAlignment.Fill + + imageSource: "asset:///images/background.png" + } + + Container { + horizontalAlignment: HorizontalAlignment.Center + verticalAlignment: VerticalAlignment.Center + + Label { + horizontalAlignment: HorizontalAlignment.Center + text: _registrationHandler.statusMessage + textStyle { + base: SystemDefaults.TextStyles.BodyText + color: Color.White + } + multiline: true + } + + Button { + horizontalAlignment: HorizontalAlignment.Center + + visible: _registrationHandler.temporaryError + text: qsTr("Connect to BBM") + onClicked: { + _registrationHandler.registerApplication() + } + } + // Display the main page if the user chooses to Continue + Button { + horizontalAlignment: HorizontalAlignment.Center + visible: _registrationHandler.allowed + text: qsTr("Continue") + onClicked: { + _registrationHandler.finishRegistration() + } + } + } + } + } +} diff --git a/bbmcontacts/assets/images/avatarPlaceholder.png b/bbmcontacts/assets/images/avatarPlaceholder.png new file mode 100644 index 00000000..a853654a Binary files /dev/null and b/bbmcontacts/assets/images/avatarPlaceholder.png differ diff --git a/bbmcontacts/assets/images/background.png b/bbmcontacts/assets/images/background.png new file mode 100644 index 00000000..92924a9e Binary files /dev/null and b/bbmcontacts/assets/images/background.png differ diff --git a/bbmcontacts/assets/images/background_blurred.png b/bbmcontacts/assets/images/background_blurred.png new file mode 100644 index 00000000..99be731f Binary files /dev/null and b/bbmcontacts/assets/images/background_blurred.png differ diff --git a/bbmcontacts/assets/images/busy.png b/bbmcontacts/assets/images/busy.png new file mode 100644 index 00000000..581f363e Binary files /dev/null and b/bbmcontacts/assets/images/busy.png differ diff --git a/bbmcontacts/bar-descriptor.xml b/bbmcontacts/bar-descriptor.xml new file mode 100644 index 00000000..e2a21f4f --- /dev/null +++ b/bbmcontacts/bar-descriptor.xml @@ -0,0 +1,104 @@ + + + + + + + + com.example.bb10samples.bbmcontacts + + + bbmcontacts + + + 1.0.0 + + + 1 + + + + + + The bbmcontacts application + + + + + + RIM + + + + + + true + none + false + + + + core.games + + armle-v7 + bbmcontacts + + + Qnx/Cascades + armle-v7 + bbmcontacts.so + + + armle-v7 + bbmcontacts + + + x86 + bbmcontacts + + + + + icon.png + + + icon.png + assets + + + + + + + + run_native + bbm_connect + + + diff --git a/bbmcontacts/bbmcontacts.pro b/bbmcontacts/bbmcontacts.pro new file mode 100644 index 00000000..8d2d7cbc --- /dev/null +++ b/bbmcontacts/bbmcontacts.pro @@ -0,0 +1,23 @@ +APP_NAME = bbmcontacts + +CONFIG += qt warn_on cascades10 + +LIBS += -lbbplatformbbm -lbbsystem + +include(config.pri) + +device { + CONFIG(debug, debug|release) { + # Device-Debug custom configuration + } + + CONFIG(release, debug|release) { + # Device-Release custom configuration + } +} + +simulator { + CONFIG(debug, debug|release) { + # Simulator-Debug custom configuration + } +} diff --git a/bbmcontacts/icon.png b/bbmcontacts/icon.png new file mode 100644 index 00000000..1b09a986 Binary files /dev/null and b/bbmcontacts/icon.png differ diff --git a/bbmcontacts/precompiled.h b/bbmcontacts/precompiled.h new file mode 100644 index 00000000..6213dc4b --- /dev/null +++ b/bbmcontacts/precompiled.h @@ -0,0 +1,2 @@ +// This file is used to store precompiled headers. +// It is intentionally left blank. It is up to you to decide which headers should be included here. diff --git a/bbmcontacts/readme.txt b/bbmcontacts/readme.txt new file mode 100644 index 00000000..3a6e4321 --- /dev/null +++ b/bbmcontacts/readme.txt @@ -0,0 +1,49 @@ +bbmcontacts + +Demonstrates how to register an application with the BlackBerry Messenger Social Platform +and access the user's BBM Contacts (who also have the application installed). + + + +BEFORE YOU RUN THIS SAMPLE +Edit the main method in main.cpp and set your own UUID (Universally unique identifier). + + +Feature Summary + +BlackBerry Messenger Social Platform Registration +BlackBerry Messenger Social Platform Contact Access + +Author(s) + +Mark Sohm + + +Requirements + +BlackBerry Native SDK 10. +BlackBerry 10 Device + + +Importing a project into the Native SDK + +From the the Sample apps page, download and extract the sample application. +Launch the Native SDK. +On the File menu, click Import. +Expand General, and select Existing Projects into Workspace. Click Next. +Browse to the location where you extracted the sample app, and click OK. The sample project should display in the the Projects section. +Click Finish to import the project into your workspace. + + +To contribute code to this repository you must be signed up as an official contributor. + +Contributing Changes +Please see the README of the Samples-for-Java repository for instructions on how to add new Samples or make modifications to existing Samples. + + +Bug Reporting and Feature Requests +If you find a bug in a Sample, or have an enhancement request, simply file an Issue for the Sample and send a message (via github messages) to the Sample Author(s) to let them know that you have filed an Issue. + + +Disclaimer +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/bbmcontacts/src/Contact.cpp b/bbmcontacts/src/Contact.cpp new file mode 100644 index 00000000..50b1c16a --- /dev/null +++ b/bbmcontacts/src/Contact.cpp @@ -0,0 +1,90 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "Contact.hpp" + +//! [0] +Contact::Contact(const bb::platform::bbm::Contact &contact) : + m_bbmspContact(contact) { + // Load the place holder for the display image (avatar) + // Image by Decosigner: http://openclipart.org/detail/104977/help-orb-button-by-decosigner + m_avatar = bb::cascades::Image(QUrl("asset:///images/avatarPlaceholder.png")); +} +//! [0] + +Contact::~Contact() { +} + +QString Contact::ppid() { + return m_bbmspContact.ppId(); +} + +QString Contact::handle() { + return m_bbmspContact.handle(); +} + +QString Contact::appVersion() { + return m_bbmspContact.applicationVersion(); +} + +QString Contact::platformVersion() { + return QString::number(m_bbmspContact.platformVersion()); +} + +//! [1] +QString Contact::displayName() { + return m_bbmspContact.displayName(); +} + +QString Contact::personalMessage() { + return m_bbmspContact.personalMessage(); +} +//! [1] + +QString Contact::statusMessage() { + return m_bbmspContact.statusMessage(); +} + +bool Contact::busy() const { + if (m_bbmspContact.status() == bb::platform::bbm::UserStatus::Busy) { + return true; + } + return false; +} + +//! [2] +void Contact::avatarUpdated(const QString& handle, + const bb::platform::bbm::ImageType::Type imageType, + const QByteArray& displayPicture) { + + Q_UNUSED(imageType); + //Verify the update handle corresponds to this contact handle + if (QString::compare(m_bbmspContact.handle(), handle) == 0) { + // Verify that there is an image to be set. + if(displayPicture.size() != 0) { + setAvatar(displayPicture); + } + } +} + +void Contact::setAvatar(const QByteArray &imageData) { + m_avatar = bb::cascades::Image(imageData); + Q_EMIT avatarChanged(); +} +//! [2] + +QVariant Contact::avatar() { + return QVariant::fromValue(m_avatar); +} diff --git a/bbmcontacts/src/Contact.hpp b/bbmcontacts/src/Contact.hpp new file mode 100644 index 00000000..5886f319 --- /dev/null +++ b/bbmcontacts/src/Contact.hpp @@ -0,0 +1,92 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef CONTACT_HPP +#define CONTACT_HPP + +#include +#include +#include + +//! [0] +class Contact: public QObject +{ + Q_OBJECT + // Property to display contacts handle + Q_PROPERTY(QString handle READ handle NOTIFY contactChanged) + + // Property to indicate users ppId + Q_PROPERTY(QString ppid READ ppid NOTIFY contactChanged) + + // Property that indicates this app version running on the contacts device + Q_PROPERTY(QString appVersion READ appVersion NOTIFY contactChanged) + + // BBM Social Platform version that is running on a contact's device + Q_PROPERTY(QString platformVersion READ platformVersion NOTIFY contactChanged) + + // The contacts display name + Q_PROPERTY(QString displayName READ displayName NOTIFY contactChanged) + + // The contacts personal message + Q_PROPERTY(QString personalMessage READ personalMessage NOTIFY contactChanged) + + // The contacts status + Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY contactChanged) + + // Property to indicate contacts availability + Q_PROPERTY(bool busy READ busy NOTIFY contactChanged) + + // The contacts avatar image + Q_PROPERTY(QVariant avatar READ avatar NOTIFY avatarChanged) + +public: + Contact() { } + + /** + * Default constructor. + */ + Contact(const bb::platform::bbm::Contact &contact); + ~Contact(); + + QString handle(); + QString ppid(); + QString appVersion(); + QString platformVersion(); + QString displayName(); + QString personalMessage(); + QString statusMessage(); + // Returns true if the contact's status is busy; otherwise, returns false. + bool busy() const; + QVariant avatar(); + +Q_SIGNALS: + // Emitted when contact info changes + void contactChanged(); + // Emitted when contact avatar changes + void avatarChanged(); + +public Q_SLOTS: + // Corresponds to the bb::platform::bbm::ContactService::displayPictureUpdate() signal + void avatarUpdated (const QString &handle, const bb::platform::bbm::ImageType::Type imageType, const QByteArray &displayPicture); + +private: + void setAvatar(const QByteArray &imageData); + const bb::platform::bbm::Contact m_bbmspContact; + bb::cascades::Image m_avatar; +}; +//! [0] +Q_DECLARE_METATYPE(Contact *); + +#endif /* CONTACT_HPP */ diff --git a/bbmcontacts/src/ContactsDisplay.cpp b/bbmcontacts/src/ContactsDisplay.cpp new file mode 100644 index 00000000..8adef1be --- /dev/null +++ b/bbmcontacts/src/ContactsDisplay.cpp @@ -0,0 +1,126 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "ContactsDisplay.hpp" + +#include +#include +#include +#include +#include +#include +#include + +using namespace bb::cascades; + +//! [0] +ContactsDisplay::ContactsDisplay(bb::platform::bbm::Context &context, QObject *parent) + : QObject(parent) + , m_context(&context) + , m_contactsDataModel(new QListDataModel()) + , m_contactService(0) +{ + m_contactsDataModel->setParent(this); +} +//! [0] + +//! [1] +void ContactsDisplay::show() +{ + // Create the UI + QmlDocument *qml = QmlDocument::create("asset:///ContactList.qml").parent(this); + AbstractPane *root = qml->createRootObject(); + Application::instance()->setScene(root); + + m_contactService = new bb::platform::bbm::ContactService(m_context, this); + + // Connect the update signals to the model update slot + bool ok = QObject::connect(m_contactService, SIGNAL(contactListUpdated()), this, SLOT (updateModel())); + Q_ASSERT(ok); + + ok = QObject::connect(m_contactService, SIGNAL(applicationEnabled(const QString&)), this, SLOT (updateModel())); + Q_ASSERT(ok); + + ok = QObject::connect(m_contactService, SIGNAL(applicationDisabled(const QString&)), this, SLOT (updateModel())); + Q_ASSERT(ok); + + ok = QObject::connect(m_contactService, SIGNAL(contactUpdated(const QString&)), this, SLOT(contactUpdated(const QString&))); + Q_ASSERT(ok); + + if (m_contactService->isValid()) { + updateModel(); + } + + // Retrieve the Field.qml custom component and set it's value + QObject* contactCountField = root->findChild("contactCount"); + QString contCount = QString("%1").arg(m_contactService->contactCount()); + + contactCountField->setProperty("value", contCount); + + // Retrieve the ListView and set its datamodel + ListView* contactListView = root->findChild("contactListView"); + contactListView->setDataModel(m_contactsDataModel); + + qDebug() << contCount; +} +//! [1] + +//! [2] +void ContactsDisplay::updateModel() { + QList contacts = m_contactService->contacts(); + m_contactsDataModel->clear(); + + // For each bbm::Contact created a Contact and add it to the ListView datamodel + for (int i = 0; i < contacts.size(); i++) + { + Contact* bbm_contact = new Contact(contacts.at(i)); + m_contactsDataModel->append(bbm_contact); + // Signal-Slot connection for updating contact avatar + bool ok = connect(m_contactService, SIGNAL(displayPictureUpdated(const QString&, const bb::platform::bbm::ImageType::Type + , const QByteArray&)) + , bbm_contact + , SLOT(avatarUpdated(const QString& + , const bb::platform::bbm::ImageType::Type + , const QByteArray&))); + Q_ASSERT(ok); + m_contactService->requestDisplayPicture(bbm_contact->handle()); + } +} +//! [2] + +//! [3] +void ContactsDisplay::contactUpdated(const QString& handle) { + for(int i = 0; i < m_contactsDataModel->size(); i++) { + QVariantList index; + index << i; + Contact *contact = m_contactsDataModel->value(i); + // Once the right contact handle is found, replace the old Contact instance + // with the new updated one. + if(QString::compare(contact->handle(), handle) == 0) { + Contact* new_contact = new Contact(m_contactService->contact(handle)); + // Signal-Slot connection for updating contact avatar + bool ok = connect(m_contactService, SIGNAL(displayPictureUpdated(const QString&, const bb::platform::bbm::ImageType::Type + , const QByteArray&)) + , new_contact + , SLOT(avatarUpdated(const QString& + , const bb::platform::bbm::ImageType::Type + , const QByteArray&))); + Q_ASSERT(ok); + m_contactService->requestDisplayPicture(new_contact->handle()); + m_contactsDataModel->replace(i, new_contact); + } + } +} +//! [3] diff --git a/bbmcontacts/src/ContactsDisplay.hpp b/bbmcontacts/src/ContactsDisplay.hpp new file mode 100644 index 00000000..3ea3cb76 --- /dev/null +++ b/bbmcontacts/src/ContactsDisplay.hpp @@ -0,0 +1,73 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef CONTACSDISPLAY_HPP +#define CONTACSDISPLAY_HPP + +#include "Contact.hpp" + +#include + +namespace bb { +namespace platform { +namespace bbm { +class Context; +class ContactService; +} +} +} + +/** + * This class deals mainly with the ContactService and + * the updating of the ListView model to reflect up-to-date + * content. + */ +//! [0] +class ContactsDisplay: public QObject +{ + Q_OBJECT + +public: + /** + * Default Constructor. + */ + ContactsDisplay(bb::platform::bbm::Context &context, QObject *parent = 0); + +public Q_SLOTS: + /** + * Creates the ContactList qml document and sets + * the application scene to it. + */ + void show(); + + /** + * Updates the ListView model with your bbm contacts. + */ + void updateModel(); + + /** + * Updates the contact in the datamodel with the + * contact changes. + */ + void contactUpdated(const QString &handle); + +private: + bb::platform::bbm::Context *m_context; + bb::cascades::QListDataModel* m_contactsDataModel; + bb::platform::bbm::ContactService * m_contactService; + +}; +//! [0] +#endif /* CONTACSDISPLAY_HPP */ diff --git a/bbmcontacts/src/RegistrationHandler.cpp b/bbmcontacts/src/RegistrationHandler.cpp new file mode 100644 index 00000000..b060c6c4 --- /dev/null +++ b/bbmcontacts/src/RegistrationHandler.cpp @@ -0,0 +1,225 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "RegistrationHandler.hpp" + +#include +#include +#include +#include + +#include +#include + +using namespace bb::cascades; +using namespace bb::platform::bbm; +using namespace bb::system; + + +RegistrationHandler::RegistrationHandler(const QUuid &uuid, QObject *parent) + : QObject(parent) + , m_context(uuid) + , m_isAllowed(false) + , m_progress(BbmRegistrationProgress::NotStarted) + , m_temporaryError(false) + , m_statusMessage(tr("Please wait while the application connects to BBM.")) +{ + QmlDocument* qml = QmlDocument::create("asset:///Registration.qml") + .parent(this); + qml->setContextProperty("_registrationHandler", this); + AbstractPane *root = qml->createRootObject(); + Application::instance()->setScene(root); + bool ok = false; + if (uuid.isNull()) { + SystemDialog *uuidDialog = new SystemDialog("OK"); + uuidDialog->setTitle("UUID Error"); + uuidDialog->setBody("Invalid/Empty UUID, please set correctly in main.cpp"); + + ok = connect(uuidDialog, SIGNAL(finished(bb::system::SystemUiResult::Type)), this, SLOT(dialogFinished(bb::system::SystemUiResult::Type))); + Q_ASSERT(ok); + + uuidDialog->show(); + return; + } + ok = connect(&m_context, + SIGNAL(registrationStateUpdated(bb::platform::bbm::RegistrationState::Type)) + , this + , SLOT(processRegistrationStatus(bb::platform::bbm::RegistrationState::Type))); + Q_ASSERT(ok); +} + +void RegistrationHandler::registerApplication() +{ + m_progress = BbmRegistrationProgress::Started; + processRegistrationStatus(m_context.registrationState()); +} + +void RegistrationHandler::processRegistrationStatus(const RegistrationState::Type state) +{ + // Based on the state, decide whether we need to register. If we already + // registered successfully once (i.e. on a previous application run), then + // we will not call requestRegisterApplication() again. + qDebug() << "Received a BBM Social Platform registration access state=" + << state; + switch(m_progress) + { + case BbmRegistrationProgress::Pending: + if (state != RegistrationState::Pending) { + registrationFinished(); + return; + } + // Otherwise, ignore since registration is still in progress. + break; + + case BbmRegistrationProgress::Started: + if (m_context.isAccessAllowed()) { + // Access is allowed, the application is registered. + registrationFinished(); + return; + } + if (m_context.registrationState() == RegistrationState::Unknown) { + // Status is not yet known. Wait for an event that will deliver the + // status. + qDebug() << "BBM Social Platform access state is UNKNOWN; waiting " + "for the initial status"; + return; + } + // Start registration. + if (m_context.requestRegisterApplication()) { + // Registration started. The user will see a dialog informing them + // that your application is connecting to BBM. + m_progress = BbmRegistrationProgress::Pending; + qDebug() << "BBM Social Platform registration started"; + qDebug() << "Verify you are using a valid UUID"; + return; + } + // Could not start registration. No dialogs were shown. + qDebug() << "BBM Social Platform registration could not be started"; + registrationFinished(); + break; + + case BbmRegistrationProgress::Finished: + if (m_context.isAccessAllowed() != m_isAllowed) { + // Access to the BBM Social Platform has changed. + registrationFinished(); + } + break; + + default: + qDebug() << "Ignoring BBM Social Platform access state=" << state + << "when progress=" << m_progress; + break; + } +} + +void RegistrationHandler::registrationFinished() +{ + // Finish registration and use the state to decide which message to show + // the user. + m_progress = BbmRegistrationProgress::Finished; + switch (m_context.registrationState()) { + case RegistrationState::Allowed: + m_statusMessage = tr("Application connected to BBM. Press Continue."); + m_temporaryError = false; + break; + +// This error code is not yet available in the NDK. +// case RegistrationState::BbmDisabled: +// m_statusMessage = tr("Cannot connect to BBM. BBM is not setup. " +// "Open BBM to set it up and try again."); +// m_temporaryError = false; +// break; + + case RegistrationState::BlockedByRIM: + m_statusMessage = tr("Disconnected by RIM. RIM is preventing this " + "application from connecting to BBM."); + m_temporaryError = false; + break; + + case RegistrationState::BlockedByUser: + m_statusMessage = tr("Disconnected. Go to Settings -> Security and " + "Privacy -> Application Permissions and " + "connect this application to BBM."); + m_temporaryError = false; + break; + + case RegistrationState::InvalidUuid: + // You should be resolving this error at development time. + m_statusMessage = tr("Invalid UUID. Report this error to the " + "vendor."); + m_temporaryError = true; + break; + + case RegistrationState::MaxAppsReached: + m_statusMessage = tr("Too many applications are connected to BBM. " + "Uninstall one or more applications and try " + "again."); + m_temporaryError = false; + break; + + case RegistrationState::Expired: + case RegistrationState::MaxDownloadsReached: + m_statusMessage = tr("Cannot connect to BBM. Download this " + "application from AppWorld to keep using it."); + m_temporaryError = false; + break; + + case RegistrationState::NoDataConnection: + m_statusMessage = tr("Check your Internet connection and try again."); + m_temporaryError = true; + break; + + case RegistrationState::Pending: + // The user will never see this. The BBM Social Platform already + // displays a "Connecting" dialog. + m_statusMessage = tr("Connecting to BBM. Please wait."); + m_temporaryError = false; + break; + + case RegistrationState::Unknown: + m_statusMessage = tr("Determining the status. Please wait."); + m_temporaryError = false; + break; + + case RegistrationState::Unregistered: + case RegistrationState::UnexpectedError: + case RegistrationState::TemporaryError: + case RegistrationState::CancelledByUser: + default: + // If new error codes are added, treat them as temporary errors. + m_statusMessage = tr("Would you like to connect the application to " + "BBM?"); + m_temporaryError = true; + break; + } + + if (m_context.isAccessAllowed()) { + m_isAllowed = true; + } else { + m_isAllowed = false; + } + qDebug() << "Finished BBM Social Platform registration, success=" + << m_isAllowed << "temporaryError=" << m_temporaryError; + emit stateChanged(); +} + +void RegistrationHandler::dialogFinished(bb::system::SystemUiResult::Type value) { + Q_UNUSED(value); + Application::exit(-1); +} + +void RegistrationHandler::finishRegistration() { + emit registered(); +} diff --git a/bbmcontacts/src/RegistrationHandler.hpp b/bbmcontacts/src/RegistrationHandler.hpp new file mode 100644 index 00000000..727e9044 --- /dev/null +++ b/bbmcontacts/src/RegistrationHandler.hpp @@ -0,0 +1,153 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef REGISTRATIONHANDLER_HPP +#define REGISTRATIONHANDLER_HPP + +#include +#include +#include + +/** + * @brief A class that encapsulates the registration at the BBM Social Platform. + */ +class RegistrationHandler : public QObject +{ + Q_OBJECT + + // Flag indicating whether the application is successfully registered + // with BBM. + Q_PROPERTY(bool allowed READ isAllowed NOTIFY stateChanged) + + // The status message describing the registration process. + Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY stateChanged) + + // Flag indicating whether registration failed due to a temporary error. + // This allows the user to re-try registration. + Q_PROPERTY(bool temporaryError READ isTemporaryError NOTIFY stateChanged) + +public: + // Enumerates the possible registration progress states. + struct BbmRegistrationProgress + { + enum Type { + // Registration has not started and has never been attempted since + // the application started. + NotStarted = 0, + // Registration has started. + Started, + // Registration is in progress. + Pending, + // Registration is done. Use isRegistered() or + // Context::isAccessAllowed() to check if the application is + // registered successfully. + Finished + }; + }; + + /** + * Creates a new registration handler. + * + * @param uuid The unique ID of the application + * @param parent The parent object + */ + RegistrationHandler(const QUuid &uuid, QObject *parent = 0); + + /** + * Returns the BBM context that is associated with this application. + */ + bb::platform::bbm::Context& context() { + return m_context; + } + + /** + * Returns the registration progress. + * @see BbmRegistrationProgress::Type + */ + BbmRegistrationProgress::Type progress() const { + return m_progress; + } + +public Q_SLOTS: + /** + * This method is called to trigger the registration with the BBM Social + * Platform. Check the progress prior to calling this function to ensure + * that another registration is not in progress. + */ + void registerApplication(); + + /** + * This method is invoked in order to generate a registered signal + * on demand based on user interaction. + */ + void finishRegistration(); + +Q_SIGNALS: + // The change notification signal of the properties. + void stateChanged(); + + // The registered notification signal. + void registered(); + +private Q_SLOTS: + // This slot is invoked whenever the registration status is changed. + // This will initiate, continue, or finish registration based on the status. + // @param state is the registration state + void processRegistrationStatus(const bb::platform::bbm::RegistrationState::Type state); + + // This slot is invoked when the uuid is invalid or NULL. + // This will cause the application to exit with error code -1 + // @param value is the system ui result indicating which button was pressed + void dialogFinished(bb::system::SystemUiResult::Type value); + +private: + // Return true if registration has completed successfully. + bool isAllowed() const { + return m_isAllowed; + } + + // Return true if registration failed due to a temporary error. + bool isTemporaryError() const { + return m_temporaryError; + } + + // Return the message that describes the registration state. + const QString& statusMessage() const { + return m_statusMessage; + } + + // Registration finished. This method updates m_registered, m_statusMessage, + // and m_progress. It emits a stateChanged() signal. + void registrationFinished(); + + // BBM Social Platform Context used to gain access to BBM functionality. + bb::platform::bbm::Context m_context; + + // A flag that indicates whether registration completed successfully. + bool m_isAllowed; + + // Registration progress. Use this to check if you have already attempted + // registration, if registration has finished, or it's still in progress. + BbmRegistrationProgress::Type m_progress; + + // A flag that indicates whether registration failed due to a temporary + // error. + bool m_temporaryError; + + // A status message that describes the current state of registration. + QString m_statusMessage; +}; + +#endif diff --git a/bbmcontacts/src/main.cpp b/bbmcontacts/src/main.cpp new file mode 100644 index 00000000..a5d9dd3d --- /dev/null +++ b/bbmcontacts/src/main.cpp @@ -0,0 +1,54 @@ +/* Copyright (c) 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include + +#include +#include + +#include "RegistrationHandler.hpp" +#include "ContactsDisplay.hpp" +#include "Contact.hpp" + +using namespace bb::cascades; + +Q_DECL_EXPORT int main(int argc, char **argv) +{ + Application app(argc, argv); + qmlRegisterType("com.example.contact", 1, 0, "Contact"); + + // localization support + QTranslator translator; + const QString locale_string = QLocale().name(); + const QString filename = QString::fromLatin1("bbmprofilebox_%1").arg(locale_string); + if (translator.load(filename, "app/native/qm")) { + app.installTranslator(&translator); + } + + //TODO: Define your own UUID here. You can generate one here: http://www.guidgenerator.com/ + + const QString uuid(QLatin1String("")); + + //! [0] + RegistrationHandler *registrationHandler = new RegistrationHandler(uuid, &app); + + ContactsDisplay *contactsDisplay = new ContactsDisplay(registrationHandler->context(), &app); + + // Whenever the registration has finished successfully, we continue to the main UI + QObject::connect(registrationHandler, SIGNAL(registered()), contactsDisplay, SLOT(show())); + //! [0] + + return Application::exec(); +} diff --git a/bbmcontacts/translations/Makefile b/bbmcontacts/translations/Makefile new file mode 100644 index 00000000..a13cb1fa --- /dev/null +++ b/bbmcontacts/translations/Makefile @@ -0,0 +1,12 @@ +QMAKE_TARGET = bbmcontacts +LUPDATE = $(QNX_HOST)/usr/bin/lupdate +LRELEASE = $(QNX_HOST)/usr/bin/lrelease + +update: $(QMAKE_TARGET).pro FORCE + $(LUPDATE) $(QMAKE_TARGET).pro + +release: $(QMAKE_TARGET).pro $(QMAKE_TARGET).ts + $(LRELEASE) $(QMAKE_TARGET).pro + +FORCE: + diff --git a/bbmcontacts/translations/bbmcontacts.pro b/bbmcontacts/translations/bbmcontacts.pro new file mode 100644 index 00000000..500fcb96 --- /dev/null +++ b/bbmcontacts/translations/bbmcontacts.pro @@ -0,0 +1 @@ +include (../bbmcontacts.pro) diff --git a/bpstoqml/.cproject b/bpstoqml/.cproject new file mode 100644 index 00000000..3d92a6a6 --- /dev/null +++ b/bpstoqml/.cproject @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bpstoqml/.device b/bpstoqml/.device new file mode 100644 index 00000000..63f13701 --- /dev/null +++ b/bpstoqml/.device @@ -0,0 +1,6 @@ +#Project target device definition. +#Fri Jul 05 11:33:40 EDT 2013 +ppi=356 +height=1280 +kind=PHONE +width=768 diff --git a/bpstoqml/.project b/bpstoqml/.project new file mode 100644 index 00000000..dfb58ff3 --- /dev/null +++ b/bpstoqml/.project @@ -0,0 +1,90 @@ + + + bpstoqml + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + Device-Debug + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + true + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + Device-Debug + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder + + + + + com.rim.tad.tools.qml.core.qmlFileBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.qnx.tools.ide.bbt.core.bbtnature + org.eclipse.cdt.core.ccnature + com.rim.tad.tools.qml.core.qmlNature + + diff --git a/bpstoqml/.settings/org.eclipse.cdt.core.prefs b/bpstoqml/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 00000000..c4a5e2b3 --- /dev/null +++ b/bpstoqml/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,25 @@ +eclipse.preferences.version=1 +environment/project/com.qnx.qcc.toolChain.1166208200/CPULIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1166208200/CPULIST/operation=append +environment/project/com.qnx.qcc.toolChain.1166208200/CPULIST/value=arm +environment/project/com.qnx.qcc.toolChain.1166208200/VARIANTLIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1166208200/VARIANTLIST/operation=append +environment/project/com.qnx.qcc.toolChain.1166208200/VARIANTLIST/value=g +environment/project/com.qnx.qcc.toolChain.1166208200/append=true +environment/project/com.qnx.qcc.toolChain.1166208200/appendContributed=true +environment/project/com.qnx.qcc.toolChain.1711290786/CPULIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1711290786/CPULIST/operation=append +environment/project/com.qnx.qcc.toolChain.1711290786/CPULIST/value=x86 +environment/project/com.qnx.qcc.toolChain.1711290786/VARIANTLIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.1711290786/VARIANTLIST/operation=append +environment/project/com.qnx.qcc.toolChain.1711290786/VARIANTLIST/value=g +environment/project/com.qnx.qcc.toolChain.1711290786/append=true +environment/project/com.qnx.qcc.toolChain.1711290786/appendContributed=true +environment/project/com.qnx.qcc.toolChain.296952375/CPULIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.296952375/CPULIST/operation=append +environment/project/com.qnx.qcc.toolChain.296952375/CPULIST/value=arm +environment/project/com.qnx.qcc.toolChain.296952375/EXCLUDE_VARIANTLIST/delimiter=, +environment/project/com.qnx.qcc.toolChain.296952375/EXCLUDE_VARIANTLIST/operation=append +environment/project/com.qnx.qcc.toolChain.296952375/EXCLUDE_VARIANTLIST/value=r +environment/project/com.qnx.qcc.toolChain.296952375/append=true +environment/project/com.qnx.qcc.toolChain.296952375/appendContributed=true diff --git a/bpstoqml/LICENSE b/bpstoqml/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/bpstoqml/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + 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. + + 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, + 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 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 in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) 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 + + (d) 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 Apache License to your work. + + To apply the Apache 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 Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + + 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/bpstoqml/Makefile b/bpstoqml/Makefile new file mode 100644 index 00000000..81353b19 --- /dev/null +++ b/bpstoqml/Makefile @@ -0,0 +1,35 @@ +QMAKE_TARGET = bpstoqml +QMAKE = $(QNX_HOST)/usr/bin/qmake +TARGET = $(QMAKE_TARGET) + + +all: Makefile $(QMAKE_TARGET) + +clean: + $(MAKE) -C ./arm -f Makefile sureclean + $(MAKE) -C ./x86 -f Makefile sureclean + + +Makefile: FORCE + $(QMAKE) -spec blackberry-armv7le-qcc -o arm/Makefile $(QMAKE_TARGET).pro CONFIG+=device + $(QMAKE) -spec blackberry-x86-qcc -o x86/Makefile $(QMAKE_TARGET).pro CONFIG+=simulator + $(MAKE) -C ./translations -f Makefile update release + +FORCE: + +$(QMAKE_TARGET): device simulator + +device: + $(MAKE) -C ./arm -f Makefile all + +Device-Debug: Makefile + $(MAKE) -C ./arm -f Makefile debug + +Device-Release: Makefile + $(MAKE) -C ./arm -f Makefile release + +simulator: + $(MAKE) -C ./x86 -f Makefile all + +Simulator-Debug: Makefile + $(MAKE) -C ./x86 -f Makefile debug diff --git a/bpstoqml/NOTICE b/bpstoqml/NOTICE new file mode 100644 index 00000000..2466347a --- /dev/null +++ b/bpstoqml/NOTICE @@ -0,0 +1,9 @@ +SmartSignals +Copyright (c) 2012 Research In Motion Limited (http://www.rim.com/) + +This product includes software developed at +Research In Motion Limited (http://www.rim.com/). + +The images and logos provided in this project are proprietary to their +owners, excluded from the Apache 2.0 license, and cannot be used for +any other purpose. diff --git a/bpstoqml/README.md b/bpstoqml/README.md new file mode 100644 index 00000000..d03a5803 --- /dev/null +++ b/bpstoqml/README.md @@ -0,0 +1,35 @@ +bpstoqml - Handle C-Level BPS events in the Cascades framework + +======================================================================== +Sample Description. + +This sample shows how the AbstractBpsEventHandler interface can be extended to +receive BPS events without needing to create a separate thread. These events +are then made accessible to the QML layer by creating and registering a C++ +class, BPSMonitor, so it is known to QML. After registering this type the +developer can then register to receive various events right from QML. + +This sample can be tested either on a real device or using a simulator in pair +with controller.exe which can be used to perform sensor manipulations. + + +======================================================================== +Requirements: + +BlackBerry 10 Native SDK Beta + +======================================================================== +Running the example: + +1. Download the source code +2. Launch BlackBerry 10 Native SDK Beta, and from the File menu, select Import. +3. Expand General, and select Existing Projects into Workspace. Click Next. +4. Browse to the location of the source code project, and then click OK. +5. The sample project should display in the the Projects section. + Click Finish to import the project into your workspace. +6. In the Project Explorer pane, Right-click the the project and select Build Project. +7. In the Project Explorer pane, Right-click the the project and select + Run As > BlackBerry C/C++ Application. +8. The application will now install and launch on your device if not you might + have to set up your environment: + http://developer.blackberry.com/cascades/documentation/getting_started/setting_up.html diff --git a/bpstoqml/assets/AlertSign.qml b/bpstoqml/assets/AlertSign.qml new file mode 100644 index 00000000..ec9999b6 --- /dev/null +++ b/bpstoqml/assets/AlertSign.qml @@ -0,0 +1,87 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +import bb.cascades 1.0 + +ImageView { + id: sign + property bool activated: false + + imageSource: "asset:///images/Sign.png" + translationX: 640 + translationY: 500 + pivotY: 110 + pivotX: -50 + + attachedObjects: [ + // animations performed by framework when value of rotationZ changes + ImplicitAnimationController { + propertyName: "rotationZ" + enabled: false + } + ] + + animations: [ + SequentialAnimation { + id: swingAnimation + animations: [ + RotateTransition { + toAngleZ: 10 + duration: 100 + }, + RotateTransition { + toAngleZ: -10 + duration: 200 + }, + RotateTransition { + toAngleZ: 5 + duration: 100 + }, + RotateTransition { + toAngleZ: -5 + duration: 100 + }, + RotateTransition { + toAngleZ: 2 + duration: 100 + }, + RotateTransition { + toAngleZ: -2 + duration: 100 + }, + RotateTransition { + toAngleZ: 0 + duration: 100 + } + ] + } + ] + + function activate() { + sign.activated = true + if (swingAnimation.isPlaying()) { + swingAnimation.stop() + } + if (!swingAnimation.isPlaying()) { + swingAnimation.play() + } + sign.translationY = 320 + } + + function deactivate() { + sign.activated = false + sign.translationY = 500 + } +} diff --git a/bpstoqml/assets/CloudButton.qml b/bpstoqml/assets/CloudButton.qml new file mode 100644 index 00000000..3a520367 --- /dev/null +++ b/bpstoqml/assets/CloudButton.qml @@ -0,0 +1,79 @@ +/* Copyright (c) 2012 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +import bb.cascades 1.0 + +/** +* This class creates a custom Button rather than rely on the Button class. This is +* done for a few reasons: +* 1) It allows us to specify a custom image including a shadow +* 2) It allows us to customize the text +* 3) It allows us to customize the animation when it is interacted with by the user +*/ + +Container { + id: container + property alias imageSource: cloudImage.imageSource + property alias shadowImageSource: shadowImage.imageSource + property alias text: label.text + signal selected() + + layout: DockLayout { + } + + ImageView { + id: shadowImage + opacity: 0.5 + } + + ImageView { + id: cloudImage + } + + Label { + id: label + text: "" + verticalAlignment: VerticalAlignment.Center + horizontalAlignment: HorizontalAlignment.Center + textStyle { + fontSize: FontSize.XXLarge + color: Color.create("#5a5a5a") + } + } + + // When the button is pressed/released we display a slight animation + // to let the end-user know that something has occurred + onTouch: { + if (event.isDown()) { + container.rotationZ = 10 + container.opacity = .5 + shadowImage.translationX = -3; + shadowImage.translationY = -3; + cloudImage.translationX = 2; + cloudImage.translationY = 2; + } else if (event.isUp()) { + container.rotationZ = 0 + container.opacity = 1 + shadowImage.translationX = 0 + shadowImage.translationY = 0 + cloudImage.translationX = 0; + cloudImage.translationY = 0; + //Emit the selected() signal to notify the app that the button is pressed + selected(); + } + } + + +} diff --git a/bpstoqml/assets/StatusBar.qml b/bpstoqml/assets/StatusBar.qml new file mode 100644 index 00000000..1d468cdd --- /dev/null +++ b/bpstoqml/assets/StatusBar.qml @@ -0,0 +1,48 @@ +/* Copyright (c) 2012 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +import bb.cascades 1.0 + + Container { + layout: DockLayout {} + + //Refer to StatusBarLabel.qml for more info on this + StatusBarLabel { id: label0 } + StatusBarLabel { id: label1 } + + //This section performs an animation on the StatusBarLabel when the label switches + function setText(text) { + var incomingLabel = null + var outgoingLabel = null + if (label1.opacity == 0) { + incomingLabel = label1 + outgoingLabel = label0 + } else { + incomingLabel = label0 + outgoingLabel = label1 + } + if (outgoingLabel.text !== text) { + incomingLabel.text = text; + incomingLabel.opacity = 1; + incomingLabel.translationY = 0 + incomingLabel.scaleX = 1 + incomingLabel.scaleY = 1 + outgoingLabel.opacity = 0 + outgoingLabel.translationY = 200 + outgoingLabel.scaleX = .1 + outgoingLabel.scaleY = .1 + } + } + } \ No newline at end of file diff --git a/bpstoqml/assets/StatusBarLabel.qml b/bpstoqml/assets/StatusBarLabel.qml new file mode 100644 index 00000000..21ca0b22 --- /dev/null +++ b/bpstoqml/assets/StatusBarLabel.qml @@ -0,0 +1,32 @@ +/* Copyright (c) 2012 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +import bb.cascades 1.0 + +//This class is a label which is used to display status updates +//from interaction with the application or sensors + +Label { + opacity: 0 + translationY: 200 + scaleX: .1 + scaleY: .1 + verticalAlignment: VerticalAlignment.Center + horizontalAlignment: HorizontalAlignment.Center + textStyle { + fontSizeValue: 42 + color: Color.White + } +} \ No newline at end of file diff --git a/bpstoqml/assets/images/Cloud1.png b/bpstoqml/assets/images/Cloud1.png new file mode 100644 index 00000000..a384997d Binary files /dev/null and b/bpstoqml/assets/images/Cloud1.png differ diff --git a/bpstoqml/assets/images/Cloud1_shadow.png b/bpstoqml/assets/images/Cloud1_shadow.png new file mode 100644 index 00000000..0a868b7c Binary files /dev/null and b/bpstoqml/assets/images/Cloud1_shadow.png differ diff --git a/bpstoqml/assets/images/Cloud2.png b/bpstoqml/assets/images/Cloud2.png new file mode 100644 index 00000000..9c837c1c Binary files /dev/null and b/bpstoqml/assets/images/Cloud2.png differ diff --git a/bpstoqml/assets/images/Cloud2_shadow.png b/bpstoqml/assets/images/Cloud2_shadow.png new file mode 100644 index 00000000..bf0745b4 Binary files /dev/null and b/bpstoqml/assets/images/Cloud2_shadow.png differ diff --git a/bpstoqml/assets/images/Cloud3.png b/bpstoqml/assets/images/Cloud3.png new file mode 100644 index 00000000..8c506866 Binary files /dev/null and b/bpstoqml/assets/images/Cloud3.png differ diff --git a/bpstoqml/assets/images/Cloud3_shadow.png b/bpstoqml/assets/images/Cloud3_shadow.png new file mode 100644 index 00000000..6aa21d1b Binary files /dev/null and b/bpstoqml/assets/images/Cloud3_shadow.png differ diff --git a/bpstoqml/assets/images/Hills.png b/bpstoqml/assets/images/Hills.png new file mode 100644 index 00000000..2b2369aa Binary files /dev/null and b/bpstoqml/assets/images/Hills.png differ diff --git a/bpstoqml/assets/images/Sign.png b/bpstoqml/assets/images/Sign.png new file mode 100644 index 00000000..e47f4844 Binary files /dev/null and b/bpstoqml/assets/images/Sign.png differ diff --git a/bpstoqml/assets/images/Sky.png b/bpstoqml/assets/images/Sky.png new file mode 100644 index 00000000..51237d4e Binary files /dev/null and b/bpstoqml/assets/images/Sky.png differ diff --git a/bpstoqml/assets/main.qml b/bpstoqml/assets/main.qml new file mode 100644 index 00000000..fa79c1d6 --- /dev/null +++ b/bpstoqml/assets/main.qml @@ -0,0 +1,199 @@ +/* Copyright (c) 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import bb.cascades 1.0 +import bb.cascades.bps 1.0 + +/** + * Use the controller.exe bundled with the simulator to manipulate the sensor + * readings and get a feel for how these events can be used within your application. + */ + +Page { + content: Container { + attachedObjects: [ + //![0] + /* + * This entire block of code initializes the BlackBerry Platform Services (BPS) + * Monitor (BPSMonitor) class written in C++ and registers the sensors for which + * we would like to receive events + */ + BPSMonitor { + id: bpsMonitor + //! [1] + //Receive events when the Azimuth Pitch and Roll change + azimuthPitchRollService: AzimuthPitchRollService { + onAzimuthPitchRollData: { + cloud3.rotationZ = roll + cloud2.rotationZ = pitch + cloud1.rotationZ = azimuth + } + } + //! [1] + //! [2] + //Receive events when the ambient light around the device changes + lightService: LightService { + id: lightService + onIlluminanceData: { + if (illuminance == 0) { + alertSign.opacity = 1; + } else { + // This calculation is a bit ugly but it gives a linear scale when + // simulating illuminance changes from controller.exe. It may be best + // to remove this when testing with a real device. + var logIlluminance = 1 - Math.pow(illuminance, 1 / 5) / 9.177; + // Set the opacity of the AlertSign to reflect the amount of light + // the device is currently receiving + alertSign.opacity = logIlluminance; + } + } + } + //! [2] + //! [3] + //Receive events when the keyboard becomes visible or hides + virtualKeyboardService: VirtualKeyboardService { + id: virtualKeyboardService + // Swipe from the bottom-left bezel towards the center of the + // screen to force the keyboard to be visible + onKeyboardVisible: { + statusBar.translationY = 768 - statusBar.preferredHeight - 300 + statusBar.setText("Keyboard Visible"); + } + // Press the hide keyboard button on the keyboard to hide it + onKeyboardHidden: { + statusBar.translationY = 768 - statusBar.preferredHeight + statusBar.setText("Keyboard Hidden"); + } + } + //! [3] + //! [4] + //Receive events when the device changes locations + geolocationService: GeolocationService { + id: geolocationService + period: 20 //Receive updates every 20 seconds + onLocationUpdate: { + statusBar.setText("Location Update: " + latitude + ", " + longitude); + } + } + //! [4] + //! [5] + //Receive events when the device proximity sensor registers that the device + // has entered close proximity of another object or exited + proximityService: ProximityService { + id: proximityService + property int proximityVal: 1 + onProximityData: { + if (proximity != proximityVal) { + proximityVal = proximity; + if (proximityVal == 0) { + statusBar.setText("I need some space!"); + } else { + statusBar.setText("Space received, thank-you"); + } + } + } + } + //! [5] + } + //! [0] + ] + layout: AbsoluteLayout { + } + preferredWidth: 1280 + preferredHeight: 768 + onCreationCompleted: { + lightService.setEnableSkipDuplicates(true); + } + + // sky background + ImageView { + imageSource: "asset:///images/Sky.png" + } + //! [6] + AlertSign { + id: alertSign + } + //! [6] + ImageView { + id: hills + imageSource: "asset:///images/Hills.png" + translationY: 314.0 + } + //! [7] + Container { + preferredHeight: 350 + preferredWidth: 1280 + layout: DockLayout { + } + // Add 3 buttons to the screen, take a look at the onSelected functions + // to see what happens when these are selected. + Container { + id: cloud1 + CloudButton { + imageSource: "asset:///images/Cloud1.png" + shadowImageSource: "asset:///images/Cloud1_shadow.png" + text: "Azimuth" + onSelected: { + alertSign.activate() + statusBar.setText("Azimuth Pressed") + } + } + rotationZ: -10.0 + translationX: 19.0 + horizontalAlignment: HorizontalAlignment.Left + verticalAlignment: VerticalAlignment.Center + } + CloudButton { + id: cloud2 + imageSource: "asset:///images/Cloud2.png" + shadowImageSource: "asset:///images/Cloud2_shadow.png" + text: "Pitch" + rotationZ: 1.0 + translationY: 13.0 + onSelected: { + alertSign.deactivate() + statusBar.setText("Pitch Pressed") + } + horizontalAlignment: HorizontalAlignment.Center + verticalAlignment: VerticalAlignment.Top + } + Container { + id: cloud3 + CloudButton { + imageSource: "asset:///images/Cloud3.png" + shadowImageSource: "asset:///images/Cloud3_shadow.png" + text: "Roll" + onSelected: { + statusBar.setText("Roll Pressed") + } + } + rotationZ: 28.0 + horizontalAlignment: HorizontalAlignment.Right + verticalAlignment: VerticalAlignment.Center + } + } + //! [7] + + //! [8] + // The StatusBar will display some text notifications to the end user + StatusBar { + id: statusBar + preferredHeight: 150 + preferredWidth: 1280 + translationY: 768 - statusBar.preferredHeight + } + //! [8] + } +} diff --git a/bpstoqml/bar-descriptor.xml b/bpstoqml/bar-descriptor.xml new file mode 100644 index 00000000..2183e2cb --- /dev/null +++ b/bpstoqml/bar-descriptor.xml @@ -0,0 +1,106 @@ + + + + + + + + com.example.bpstoqml + + + bpstoqml + + + 1.0.0 + + + 1 + + + + + + The bpstoqml application + + + + + + Example Inc. + + + + + + landscape + false + none + false + + + + core.games + + armle-v7 + bpstoqml + + + armle-v7 + bpstoqml + + + armle-v7 + bpstoqml + + + x86 + bpstoqml + + + + + icon.png + + + icon.png + assets + + + + + + + + + + run_native + read_geolocation + + + diff --git a/bpstoqml/bpstoqml.pro b/bpstoqml/bpstoqml.pro new file mode 100644 index 00000000..e77f47c3 --- /dev/null +++ b/bpstoqml/bpstoqml.pro @@ -0,0 +1,48 @@ +TEMPLATE = app +TARGET = bpstoqml + +CONFIG += qt warn_on debug_and_release cascades + +INCLUDEPATH += ../src +SOURCES += ../src/*.cpp +HEADERS += ../src/*.hpp ../src/*.h + +device { + CONFIG(release, debug|release) { + DESTDIR = o.le-v7 + TEMPLATE = lib + QMAKE_CXXFLAGS_RELEASE += -fvisibility=hidden -mthumb + } + CONFIG(debug, debug|release) { + DESTDIR = o.le-v7-g + } +} + +simulator { + CONFIG(release, debug|release) { + DESTDIR = o + } + CONFIG(debug, debug|release) { + DESTDIR = o-g + } +} + +OBJECTS_DIR = $${DESTDIR}/.obj +MOC_DIR = $${DESTDIR}/.moc +RCC_DIR = $${DESTDIR}/.rcc +UI_DIR = $${DESTDIR}/.ui + +suredelete.target = sureclean +suredelete.commands = $(DEL_FILE) $${MOC_DIR}/*; $(DEL_FILE) $${RCC_DIR}/*; $(DEL_FILE) $${UI_DIR}/* +suredelete.depends = distclean + +QMAKE_EXTRA_TARGETS += suredelete + +TRANSLATIONS = \ + $${TARGET}_en_GB.ts \ + $${TARGET}_fr.ts \ + $${TARGET}_it.ts \ + $${TARGET}_de.ts \ + $${TARGET}_es.ts \ + $${TARGET}.ts + diff --git a/bpstoqml/device-assets.xml b/bpstoqml/device-assets.xml new file mode 100644 index 00000000..b941f6de --- /dev/null +++ b/bpstoqml/device-assets.xml @@ -0,0 +1,4 @@ + + + + diff --git a/bpstoqml/icon.png b/bpstoqml/icon.png new file mode 100644 index 00000000..ccc8b017 Binary files /dev/null and b/bpstoqml/icon.png differ diff --git a/bpstoqml/src/AbstractSensorService.cpp b/bpstoqml/src/AbstractSensorService.cpp new file mode 100644 index 00000000..82a24d87 --- /dev/null +++ b/bpstoqml/src/AbstractSensorService.cpp @@ -0,0 +1,108 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "AbstractSensorService.hpp" +#include + +namespace bb { +namespace cascades { +namespace bps { + +//! [0] +AbstractSensorService::AbstractSensorService(sensor_type_t sensorType, + QObject *parent) + : BlackBerryPlatformService(parent) + , m_sensorType(sensorType) +{ +} +//! [0] + +AbstractSensorService::~AbstractSensorService() { +} + +//! [1] +bool AbstractSensorService::isSupported() { + return sensor_is_supported(m_sensorType); +} + +void AbstractSensorService::setCalibrationEnabled(bool calibrationEnabled) { + m_calibrationEnabled = calibrationEnabled; + m_calibrationEnabledSet = true; +} + +void AbstractSensorService::setEnableSkipDuplicates(bool enableSkipDuplicates) { + m_enableSkipDuplicates = enableSkipDuplicates; + m_enableSkipDuplicatesSet = true; +} + +void AbstractSensorService::setEventRate(unsigned int rate) { + m_rate = rate; + m_rateSet = true; +} + +void AbstractSensorService::setBackgroundEnabled(bool backgroundEnabled) { + m_backgroundEnabled = backgroundEnabled; + m_backgroundEnabledSet = true; +} + +int AbstractSensorService::eventDomain() { + return sensor_get_domain(); +} +//! [1] + +//! [2] +void AbstractSensorService::requestEvents() { + if (m_calibrationEnabledSet) + sensor_set_calibration(m_sensorType, m_calibrationEnabled); + if (m_rateSet) + sensor_set_rate(m_sensorType, m_rate); + if (m_enableSkipDuplicatesSet) + sensor_set_skip_duplicates(m_sensorType, m_enableSkipDuplicates); + //if (m_backgroundEnabledSet) sensor_set_background(m_sensorType, m_backgroundEnabled); + sensor_request_events(m_sensorType); +} +//! [2] + +//! [3] +unsigned long long AbstractSensorService::getTimestamp(bps_event_t *event) { + //unsigned long long timestamp = sensor_event_get_timestamp(event); + unsigned long long timestamp = QDateTime::currentMSecsSinceEpoch(); + return timestamp; +} + +AbstractSensorService::SensorAccuracy AbstractSensorService::getAccuracy( + bps_event_t *event) { + SensorAccuracy accuracy = AccuracyUnreliable; + switch (sensor_event_get_accuracy(event)) { + case SENSOR_ACCURACY_UNRELIABLE: + accuracy = AccuracyUnreliable; + break; + case SENSOR_ACCURACY_LOW: + accuracy = AccuracyLow; + break; + case SENSOR_ACCURACY_MEDIUM: + accuracy = AccuracyMedium; + break; + case SENSOR_ACCURACY_HIGH: + accuracy = AccuracyHigh; + break; + } + return accuracy; +} +//! [3] + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/AbstractSensorService.hpp b/bpstoqml/src/AbstractSensorService.hpp new file mode 100644 index 00000000..e4681966 --- /dev/null +++ b/bpstoqml/src/AbstractSensorService.hpp @@ -0,0 +1,78 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef ABSTRACTSENSORSERVICE_H_ +#define ABSTRACTSENSORSERVICE_H_ + +#include "BlackBerryPlatformService.hpp" +#include + +namespace bb { +namespace cascades { +namespace bps { + +//! [0] +class AbstractSensorService: public BlackBerryPlatformService { + Q_OBJECT + Q_ENUMS(SensorAccuracy) + +public: + /** + * The accuracy levels for a sensor reading. + */ + enum SensorAccuracy { + AccuracyUnreliable = 0, + AccuracyLow = 1, + AccuracyMedium = 2, + AccuracyHigh = 3 + }; + + AbstractSensorService(sensor_type_t sensorType, QObject *parent = 0); + virtual ~AbstractSensorService(); + + Q_INVOKABLE bool isSupported(); + Q_INVOKABLE void setCalibrationEnabled(bool calibrationEnabled); + Q_INVOKABLE void setEnableSkipDuplicates(bool enableSkipDuplicates); + Q_INVOKABLE void setEventRate(unsigned int rate); + Q_INVOKABLE void setBackgroundEnabled(bool backgroundEnabled); + + virtual void requestEvents(); + virtual int eventDomain(); + +protected: + SensorAccuracy getAccuracy(bps_event_t *event); + unsigned long long getTimestamp(bps_event_t *event); + +private: + sensor_type_t m_sensorType; + bool m_calibrationEnabled; + bool m_calibrationEnabledSet; + bool m_enableSkipDuplicates; + bool m_enableSkipDuplicatesSet; + unsigned int m_rate; + bool m_rateSet; + bool m_backgroundEnabled; + bool m_backgroundEnabledSet; +}; +//! [0] + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +Q_DECLARE_METATYPE( bb::cascades::bps::AbstractSensorService::SensorAccuracy ); +QML_DECLARE_TYPE(bb::cascades::bps::AbstractSensorService) + +#endif /* ABSTRACTSENSORSERVICE_H_ */ diff --git a/bpstoqml/src/AccelerometerService.cpp b/bpstoqml/src/AccelerometerService.cpp new file mode 100644 index 00000000..e3306565 --- /dev/null +++ b/bpstoqml/src/AccelerometerService.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "AccelerometerService.hpp" +#include + +namespace bb { +namespace cascades { +namespace bps { + +//! [0] +AccelerometerService::AccelerometerService(QObject *parent) + : AbstractSensorService(SENSOR_TYPE_ACCELEROMETER, parent) +{ +} +//! [0] + +AccelerometerService::~AccelerometerService() { +} + +//! [1] +void AccelerometerService::handleEvent(bps_event_t *event) { + uint16_t code = bps_event_get_code(event); + if (code == SENSOR_ACCELEROMETER_READING) { + float x, y, z; + sensor_event_get_xyz(event, &x, &y, &z); + unsigned long long timestamp = getTimestamp(event); + SensorAccuracy accuracy = getAccuracy(event); + + Q_EMIT accelerometerData(x, y, z, timestamp, accuracy); + } +} +//! [1] + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/AccelerometerService.hpp b/bpstoqml/src/AccelerometerService.hpp new file mode 100644 index 00000000..1c6b3f8e --- /dev/null +++ b/bpstoqml/src/AccelerometerService.hpp @@ -0,0 +1,60 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef ACCELEROMETER_H_ +#define ACCELEROMETER_H_ + +#include "AbstractSensorService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +//! [0] +class AccelerometerService : public AbstractSensorService { + Q_OBJECT + +public: + AccelerometerService(QObject *parent = 0); + virtual ~AccelerometerService(); + + virtual void handleEvent(bps_event_t *event); + +Q_SIGNALS: + /** + * @brief Emitted when accelerometer data is available. + * + * @details The accelerometer measures the acceleration on each axis. + * + * @param x Acceleration minus Gx on the x-axis, in SI units (m/s^2) + * @param y Acceleration minus Gy on the y-axis, in SI units (m/s^2) + * @param z Acceleration minus Gz on the z-axis, in SI units (m/s^2) + * @param timestamp A monotonic timestamp (not date/time) that can be used to synchronize and/or + * fuse different sensor events. + * @param accuracy The accuracy of the sensor reading. + * + * @return None. + */ + void accelerometerData(float x, float y, float z, unsigned long long timestamp, SensorAccuracy accuracy); +}; +//! [0] + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::AccelerometerService) + +#endif /* ACCELEROMETER_H_ */ diff --git a/bpstoqml/src/AzimuthPitchRollService.cpp b/bpstoqml/src/AzimuthPitchRollService.cpp new file mode 100644 index 00000000..0acbca94 --- /dev/null +++ b/bpstoqml/src/AzimuthPitchRollService.cpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "AzimuthPitchRollService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +AzimuthPitchRollService::AzimuthPitchRollService(QObject *parent) + : AbstractSensorService(SENSOR_TYPE_AZIMUTH_PITCH_ROLL, parent) +{ +} + +AzimuthPitchRollService::~AzimuthPitchRollService() { +} + +void AzimuthPitchRollService::handleEvent(bps_event_t *event) { + uint16_t code = bps_event_get_code(event); + if (code == SENSOR_AZIMUTH_PITCH_ROLL_READING) { + float azimuth, pitch, roll; + sensor_event_get_apr(event, &azimuth, &pitch, &roll); + unsigned long long timestamp = getTimestamp(event); + SensorAccuracy accuracy = getAccuracy(event); + + Q_EMIT azimuthPitchRollData(azimuth, pitch, roll, timestamp, accuracy); + } +} + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/AzimuthPitchRollService.hpp b/bpstoqml/src/AzimuthPitchRollService.hpp new file mode 100644 index 00000000..9e2193d7 --- /dev/null +++ b/bpstoqml/src/AzimuthPitchRollService.hpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef AZIMUTHPITCHROLLSERVICE_H_ +#define AZIMUTHPITCHROLLSERVICE_H_ + +#include "AbstractSensorService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +class AzimuthPitchRollService: public AbstractSensorService { + Q_OBJECT + +public: + AzimuthPitchRollService(QObject *parent = 0); + virtual ~AzimuthPitchRollService(); + + virtual void handleEvent(bps_event_t *event); + +Q_SIGNALS: + void azimuthPitchRollData(float azimuth, float pitch, float roll, unsigned long long timestamp, SensorAccuracy accuracy); +}; + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::AzimuthPitchRollService) + +#endif /* AZIMUTHPITCHROLLSERVICE_H_ */ diff --git a/bpstoqml/src/BPSEventHandler.cpp b/bpstoqml/src/BPSEventHandler.cpp new file mode 100644 index 00000000..7d1847dd --- /dev/null +++ b/bpstoqml/src/BPSEventHandler.cpp @@ -0,0 +1,55 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "BPSEventHandler.hpp" +#include + +namespace bb { +namespace cascades { +namespace bps { + +BPSEventHandler::BPSEventHandler() : + AbstractBpsEventHandler() { +} + +BPSEventHandler::~BPSEventHandler() { +} + +//! [0] +void BPSEventHandler::registerService(BlackBerryPlatformService *service) { + m_services << service; + service->requestEvents(); + subscribe(service->eventDomain()); +} +//! [0] + +//! [1] +void BPSEventHandler::event(bps_event_t *event) { + if (event != NULL) { + // find the proper service object and let it handle the event + int domain = bps_event_get_domain(event); + for (int i = 0; i < m_services.size(); ++i) { + BlackBerryPlatformService *service = m_services.at(i); + if (domain == service->eventDomain()) { + service->handleEvent(event); + } + } + } +} +//! [1] +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + diff --git a/bpstoqml/src/BPSEventHandler.hpp b/bpstoqml/src/BPSEventHandler.hpp new file mode 100644 index 00000000..7599c45e --- /dev/null +++ b/bpstoqml/src/BPSEventHandler.hpp @@ -0,0 +1,50 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef BPSEVENTHANDLER_H_ +#define BPSEVENTHANDLER_H_ + +#include +#include "BlackBerryPlatformService.hpp" +namespace bb { +namespace cascades { +namespace bps { + +//! [0] +class BPSEventHandler: public bb::AbstractBpsEventHandler { +public: + BPSEventHandler(); + virtual ~BPSEventHandler(); + + void setServices(const QList &services) { + m_services = services; + } + QList &services() { + return m_services; + } + + virtual void event(bps_event_t *event); + void registerService(BlackBerryPlatformService *service); + + +private: + QList m_services; +}; +//! [0] +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +#endif /* BPSEVENTHANDLER_H_ */ diff --git a/bpstoqml/src/BPSMonitor.cpp b/bpstoqml/src/BPSMonitor.cpp new file mode 100644 index 00000000..1bd1a5ad --- /dev/null +++ b/bpstoqml/src/BPSMonitor.cpp @@ -0,0 +1,123 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "AccelerometerService.hpp" +#include "AzimuthPitchRollService.hpp" +#include "BPSEventHandler.hpp" +#include "BPSMonitor.hpp" +#include "GeolocationService.hpp" +#include "LightService.hpp" +#include "MagnetometerService.hpp" +#include "ProximityService.hpp" +#include "VirtualKeyboardService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +//! [0] +BPSMonitor::BPSMonitor(QObject *parent) + : QObject(parent) + , m_bpsEventHandler(new BPSEventHandler()) + , m_virtualKeyboardService(0) + , m_geolocationService(0) + , m_accelerometerService(0) + , m_magnetometerService(0) + , m_proximityService(0) + , m_azimuthPitchRollService(0) + , m_lightService(0) +{ +} +//! [0] + +BPSMonitor::~BPSMonitor() { + delete m_bpsEventHandler; + delete m_virtualKeyboardService; + delete m_geolocationService; + delete m_accelerometerService; + delete m_magnetometerService; + delete m_proximityService; + delete m_azimuthPitchRollService; + delete m_lightService; +} + +//! [1] +VirtualKeyboardService *BPSMonitor::virtualKeyboardService() { + return m_virtualKeyboardService; +} + +void BPSMonitor::setVirtualKeyboardService(VirtualKeyboardService *service) { + m_bpsEventHandler->registerService(service); + m_virtualKeyboardService = service; +} +//! [1] + +GeolocationService *BPSMonitor::geolocationService() { + return m_geolocationService; +} + +void BPSMonitor::setGeolocationService(GeolocationService *service) { + m_bpsEventHandler->registerService(service); + m_geolocationService = service; +} + +AccelerometerService *BPSMonitor::accelerometerService() { + return m_accelerometerService; +} + +void BPSMonitor::setAccelerometerService(AccelerometerService *service) { + m_bpsEventHandler->registerService(service); + m_accelerometerService = service; +} + +MagnetometerService *BPSMonitor::magnetometerService() { + return m_magnetometerService; +} + +void BPSMonitor::setMagnetometerService(MagnetometerService *service) { + m_bpsEventHandler->registerService(service); + m_magnetometerService = service; +} + +ProximityService *BPSMonitor::proximityService() { + return m_proximityService; +} + +void BPSMonitor::setProximityService(ProximityService *service) { + m_bpsEventHandler->registerService(service); + m_proximityService = service; +} + +AzimuthPitchRollService *BPSMonitor::azimuthPitchRollService() { + return m_azimuthPitchRollService; +} + +void BPSMonitor::setAzimuthPitchRollService(AzimuthPitchRollService *service) { + m_bpsEventHandler->registerService(service); + m_azimuthPitchRollService = service; +} + +LightService *BPSMonitor::lightService() { + return m_lightService; +} + +void BPSMonitor::setLightService(LightService *service) { + m_bpsEventHandler->registerService(service); + m_lightService = service; +} + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/BPSMonitor.hpp b/bpstoqml/src/BPSMonitor.hpp new file mode 100644 index 00000000..76ce1caf --- /dev/null +++ b/bpstoqml/src/BPSMonitor.hpp @@ -0,0 +1,93 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef BLACKBERRYPLATFORMSERVICESMONITOR_H_ +#define BLACKBERRYPLATFORMSERVICESMONITOR_H_ + +#include +#include + +struct bps_event_t; + +namespace bb { +namespace cascades { +namespace bps { + +class VirtualKeyboardService; +class GeolocationService; +class AccelerometerService; +class MagnetometerService; +class ProximityService; +class AzimuthPitchRollService; +class LightService; +class BPSEventHandler; + +//! [0] +class BPSMonitor: public QObject { + Q_OBJECT + + Q_PROPERTY(bb::cascades::bps::VirtualKeyboardService* virtualKeyboardService READ virtualKeyboardService WRITE setVirtualKeyboardService) + Q_PROPERTY(bb::cascades::bps::GeolocationService* geolocationService READ geolocationService WRITE setGeolocationService) + Q_PROPERTY(bb::cascades::bps::AccelerometerService* accelerometerService READ accelerometerService WRITE setAccelerometerService) + Q_PROPERTY(bb::cascades::bps::MagnetometerService* magnetometerService READ magnetometerService WRITE setMagnetometerService) + Q_PROPERTY(bb::cascades::bps::ProximityService* proximityService READ proximityService WRITE setProximityService) + Q_PROPERTY(bb::cascades::bps::AzimuthPitchRollService* azimuthPitchRollService READ azimuthPitchRollService WRITE setAzimuthPitchRollService) + Q_PROPERTY(bb::cascades::bps::LightService* lightService READ lightService WRITE setLightService) + +public: + explicit BPSMonitor(QObject *parent = 0); + ~BPSMonitor(); + + VirtualKeyboardService *virtualKeyboardService(); + void setVirtualKeyboardService(VirtualKeyboardService *service); + + GeolocationService *geolocationService(); + void setGeolocationService(GeolocationService *service); + + AccelerometerService *accelerometerService(); + void setAccelerometerService(AccelerometerService *service); + + MagnetometerService *magnetometerService(); + void setMagnetometerService(MagnetometerService *service); + + ProximityService *proximityService(); + void setProximityService(ProximityService *service); + + AzimuthPitchRollService *azimuthPitchRollService(); + void setAzimuthPitchRollService(AzimuthPitchRollService *service); + + LightService *lightService(); + void setLightService(LightService *service); + +private: + BPSEventHandler *m_bpsEventHandler; + VirtualKeyboardService *m_virtualKeyboardService; + GeolocationService *m_geolocationService; + AccelerometerService *m_accelerometerService; + MagnetometerService *m_magnetometerService; + ProximityService *m_proximityService; + AzimuthPitchRollService *m_azimuthPitchRollService; + LightService *m_lightService; +}; +//! [0] + + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::BPSMonitor) + +#endif /* BLACKBERRYPLATFORMSERVICESMONITOR_H_ */ diff --git a/bpstoqml/src/BlackBerryPlatformService.hpp b/bpstoqml/src/BlackBerryPlatformService.hpp new file mode 100644 index 00000000..7502d370 --- /dev/null +++ b/bpstoqml/src/BlackBerryPlatformService.hpp @@ -0,0 +1,56 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef BLACKBERRYPLATFORMSERVICE_H_ +#define BLACKBERRYPLATFORMSERVICE_H_ + +#include +#include + +struct bps_event_t; + +namespace bb { +namespace cascades { +namespace bps { + +/** + * An abstract class that defines the sensor classes + * common functionality. Leaving them to define handleEvent() + * behaviour only. + */ +//! [0] +class BlackBerryPlatformService : public QObject { + Q_OBJECT + +public: + explicit BlackBerryPlatformService(QObject *parent = 0) : QObject(parent) {} + virtual ~BlackBerryPlatformService() {} + + virtual void requestEvents() = 0; + virtual int eventDomain() = 0; + virtual void handleEvent(bps_event_t *event) = 0; + +private: + Q_DISABLE_COPY(BlackBerryPlatformService) +}; +//! [0] + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::BlackBerryPlatformService) + +#endif /* BLACKBERRYPLATFORMSERVICE_H_ */ diff --git a/bpstoqml/src/GeolocationService.cpp b/bpstoqml/src/GeolocationService.cpp new file mode 100644 index 00000000..f431295a --- /dev/null +++ b/bpstoqml/src/GeolocationService.cpp @@ -0,0 +1,80 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "GeolocationService.hpp" +#include + +namespace bb { +namespace cascades { +namespace bps { + +GeolocationService::GeolocationService(QObject *parent) + : BlackBerryPlatformService(parent) + , m_period(0) +{ +} + +GeolocationService::~GeolocationService() { +} + +void GeolocationService::requestEvents() { + geolocation_request_events(0); +} + +int GeolocationService::eventDomain() { + return geolocation_get_domain(); +} + +unsigned int GeolocationService::period() { + return m_period; +} +void GeolocationService::setPeriod(unsigned int period) { + m_period = period; + geolocation_set_period(m_period); +} + +void GeolocationService::handleEvent(bps_event_t *event) { + uint16_t code = bps_event_get_code(event); + if (code == GEOLOCATION_CANCEL) { + Q_EMIT cancel(); + } else if (code == GEOLOCATION_INFO) { + double latitude = geolocation_event_get_latitude(event); + double longitude = geolocation_event_get_longitude(event); + double accuracy = geolocation_event_get_accuracy(event); // accuracy in meters + bool isCoarse = geolocation_event_is_coarse(event); + Q_EMIT locationUpdate(latitude, longitude, accuracy, isCoarse); + + double altitude = geolocation_event_get_altitude(event); + bool isAltitudeValid = geolocation_event_is_altitude_valid(event); + double altitudeAccuracy = geolocation_event_get_altitude_accuracy( + event); + bool isAltitudeAccuracyValid = + geolocation_event_is_altitude_accuracy_valid(event); + Q_EMIT altitudeUpdate(altitude, isAltitudeValid, altitudeAccuracy, + isAltitudeAccuracyValid); + + double heading = geolocation_event_get_heading(event); + bool isHeadingValid = geolocation_event_is_heading_valid(event); + Q_EMIT headingUpdate(heading, isHeadingValid); + + double speed = geolocation_event_get_speed(event); + bool isSpeedValid = geolocation_event_is_speed_valid(event); + Q_EMIT speedUpdate(speed, isSpeedValid); + } +} + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/GeolocationService.hpp b/bpstoqml/src/GeolocationService.hpp new file mode 100644 index 00000000..88653898 --- /dev/null +++ b/bpstoqml/src/GeolocationService.hpp @@ -0,0 +1,63 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef GEOLOCATIONSERVICE_H_ +#define GEOLOCATIONSERVICE_H_ + +#include "BlackBerryPlatformService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +class GeolocationService: public BlackBerryPlatformService { +Q_OBJECT +Q_PROPERTY( unsigned int period READ period WRITE setPeriod ) + +public: + GeolocationService(QObject *parent = 0); + ~GeolocationService(); + + virtual void requestEvents(); + virtual int eventDomain(); + virtual void handleEvent(bps_event_t *event); + + /* Sets the period (in seconds) at which geolocation events are reported. + * If the period is set to 0, a single geolocation event is delivered, and + * no more geolocation events are delivered subsequently. + */ + unsigned int period(); + void setPeriod(unsigned int period); + +Q_SIGNALS: + void cancel(); + void locationUpdate(double latitude, double longitude, double accuracy, + bool isCoarse); + void altitudeUpdate(double altitude, bool isAltitudeValid, + double altitudeAccuracy, bool isAltitudeAccuracyValid); + void headingUpdate(double heading, bool isHeadingValid); + void speedUpdate(double speed, bool isSpeedValid); + +private: + unsigned int m_period; +}; + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::GeolocationService) + +#endif /* GEOLOCATIONSERVICE_H_ */ diff --git a/bpstoqml/src/LightService.cpp b/bpstoqml/src/LightService.cpp new file mode 100644 index 00000000..ad2edf2e --- /dev/null +++ b/bpstoqml/src/LightService.cpp @@ -0,0 +1,43 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "LightService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +LightService::LightService(QObject *parent) + : AbstractSensorService(SENSOR_TYPE_LIGHT, parent) +{ +} + +LightService::~LightService() { +} + +void LightService::handleEvent(bps_event_t *event) { + uint16_t code = bps_event_get_code(event); + if (code == SENSOR_LIGHT_READING) { + float illuminance = sensor_event_get_illuminance(event); + unsigned long long timestamp = getTimestamp(event); + SensorAccuracy accuracy = getAccuracy(event); + + Q_EMIT illuminanceData(illuminance, timestamp, accuracy); + } +} + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/LightService.hpp b/bpstoqml/src/LightService.hpp new file mode 100644 index 00000000..4a93223c --- /dev/null +++ b/bpstoqml/src/LightService.hpp @@ -0,0 +1,47 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef LIGHTSERVICE_H_ +#define LIGHTSERVICE_H_ + +#include "AbstractSensorService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +class LightService: public AbstractSensorService { + Q_OBJECT + +public: + LightService(QObject *parent = 0); + virtual ~LightService(); + + virtual void handleEvent(bps_event_t *event); + +Q_SIGNALS: + /** + * Emitted when Light sensor data available. + */ + void illuminanceData(float illuminance, unsigned long long timestamp, SensorAccuracy accuracy); +}; + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::LightService) + +#endif /* LIGHTSERVICE_H_ */ diff --git a/bpstoqml/src/MagnetometerService.cpp b/bpstoqml/src/MagnetometerService.cpp new file mode 100644 index 00000000..18fb6b36 --- /dev/null +++ b/bpstoqml/src/MagnetometerService.cpp @@ -0,0 +1,45 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "MagnetometerService.hpp" +#include + +namespace bb { +namespace cascades { +namespace bps { + +MagnetometerService::MagnetometerService(QObject *parent) + : AbstractSensorService(SENSOR_TYPE_MAGNETOMETER, parent) +{ +} + +MagnetometerService::~MagnetometerService() { +} + +void MagnetometerService::handleEvent(bps_event_t *event) { + uint16_t code = bps_event_get_code(event); + if (code == SENSOR_MAGNETOMETER_READING) { + float x, y, z; + sensor_event_get_xyz(event, &x, &y, &z); + unsigned long long timestamp = getTimestamp(event); + SensorAccuracy accuracy = getAccuracy(event); + + Q_EMIT magnetometerData(x, y, z, timestamp, accuracy); + } +} + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/MagnetometerService.hpp b/bpstoqml/src/MagnetometerService.hpp new file mode 100644 index 00000000..5beac80d --- /dev/null +++ b/bpstoqml/src/MagnetometerService.hpp @@ -0,0 +1,58 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef MAGNETOMETERSERVICE_H_ +#define MAGNETOMETERSERVICE_H_ + +#include "AbstractSensorService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +class MagnetometerService: public bb::cascades::bps::AbstractSensorService { + Q_OBJECT + +public: + MagnetometerService(QObject *parent = 0); + virtual ~MagnetometerService(); + + virtual void handleEvent(bps_event_t *event); + +Q_SIGNALS: + /** + * @brief Emitted when magnetometer data is available. + * + * @details The magnetometer measures the ambient magnetic field in each axis, in micro-Tesla (uT). + * + * @param x The ambient magnetic field in the x-axis, in micro-Tesla (uT) + * @param y The ambient magnetic field in the y-axis, in micro-Tesla (uT) + * @param z The ambient magnetic field in the z-axis, in micro-Tesla (uT) + * @param timestamp A monotonic timestamp (not date/time) that can be used to synchronize and/or + * fuse different sensor events. + * @param accuracy The accuracy of the sensor reading. + * + * @return None. + */ + void magnetometerData(float x, float y, float z, unsigned long long timestamp, SensorAccuracy accuracy); +}; + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::MagnetometerService) + +#endif /* MAGNETOMETERSERVICE_H_ */ diff --git a/bpstoqml/src/ProximityService.cpp b/bpstoqml/src/ProximityService.cpp new file mode 100644 index 00000000..a20f0935 --- /dev/null +++ b/bpstoqml/src/ProximityService.cpp @@ -0,0 +1,43 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "ProximityService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +ProximityService::ProximityService(QObject *parent) + : AbstractSensorService(SENSOR_TYPE_PROXIMITY, parent) +{ +} + +ProximityService::~ProximityService() { +} + +void ProximityService::handleEvent(bps_event_t *event) { + uint16_t code = bps_event_get_code(event); + if (code == SENSOR_PROXIMITY_READING) { + float proximity = sensor_event_get_proximity(event); + unsigned long long timestamp = getTimestamp(event); + SensorAccuracy accuracy = getAccuracy(event); + + Q_EMIT proximityData(proximity, timestamp, accuracy); + } +} + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/ProximityService.hpp b/bpstoqml/src/ProximityService.hpp new file mode 100644 index 00000000..04b1997f --- /dev/null +++ b/bpstoqml/src/ProximityService.hpp @@ -0,0 +1,47 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef PROXIMITYSERVICE_H_ +#define PROXIMITYSERVICE_H_ + +#include "AbstractSensorService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +/** + * Class that deals with proximity sensor events. + */ +class ProximityService: public bb::cascades::bps::AbstractSensorService { + Q_OBJECT + +public: + ProximityService(QObject *parent = 0); + virtual ~ProximityService(); + + virtual void handleEvent(bps_event_t *event); + +Q_SIGNALS: + void proximityData(float proximity, unsigned long long timestamp, SensorAccuracy accuracy); +}; + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::ProximityService) + +#endif /* PROXIMITYSERVICE_H_ */ diff --git a/bpstoqml/src/SmartSignalsApp.cpp b/bpstoqml/src/SmartSignalsApp.cpp new file mode 100644 index 00000000..d476a0a9 --- /dev/null +++ b/bpstoqml/src/SmartSignalsApp.cpp @@ -0,0 +1,40 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include +#include +#include +#include +#include + +#include "SmartSignalsApp.hpp" + +using namespace bb::cascades; + +SmartSignalsApp::SmartSignalsApp() { + // Load the UI description from main.qml + QmlDocument *qml = QmlDocument::create("asset:///main.qml"); + if (qml->hasErrors()) { + QList errors = qml->errors(); + qDebug() << "Errors occurred parsing qml:"; + qDebug() << &errors; + } else { + qml->setContextProperty("cs", this); + + // Create the application scene + AbstractPane *root = qml->createRootObject(); + Application::instance()->setScene(root); + } +} diff --git a/bpstoqml/src/SmartSignalsApp.hpp b/bpstoqml/src/SmartSignalsApp.hpp new file mode 100644 index 00000000..021d9205 --- /dev/null +++ b/bpstoqml/src/SmartSignalsApp.hpp @@ -0,0 +1,27 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef SMARTSIGNALSAPP_H +#define SMARTSIGNALSAPP_H + +#include + +class SmartSignalsApp : public QObject { + Q_OBJECT +public: + SmartSignalsApp(); +}; + +#endif // ifndef SMARTSIGNALSAPP_H diff --git a/bpstoqml/src/VirtualKeyboardService.cpp b/bpstoqml/src/VirtualKeyboardService.cpp new file mode 100644 index 00000000..ee6d10d4 --- /dev/null +++ b/bpstoqml/src/VirtualKeyboardService.cpp @@ -0,0 +1,58 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "VirtualKeyboardService.hpp" +#include "bps/virtualkeyboard.h" + +#include + + +namespace bb { +namespace cascades { +namespace bps { + +VirtualKeyboardService::VirtualKeyboardService(QObject *parent) + : BlackBerryPlatformService(parent) +{ +} + +VirtualKeyboardService::~VirtualKeyboardService() { +} + +void VirtualKeyboardService::requestEvents() { + virtualkeyboard_request_events(0); +} + +int VirtualKeyboardService::eventDomain() { + return virtualkeyboard_get_domain(); +} + +void VirtualKeyboardService::handleEvent(bps_event_t *event) { + uint16_t code = bps_event_get_code(event); + if (code == VIRTUALKEYBOARD_EVENT_VISIBLE) { + Q_EMIT keyboardVisible(); + } else if (code == VIRTUALKEYBOARD_EVENT_HIDDEN) { + Q_EMIT keyboardHidden(); + } else if (code == VIRTUALKEYBOARD_EVENT_INFO) { + int height = virtualkeyboard_event_get_height(event); + Q_EMIT keyboardInfo(height); + } else { + qDebug() << "Unhandled keyboard event code: " << code; + } +} + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ diff --git a/bpstoqml/src/VirtualKeyboardService.hpp b/bpstoqml/src/VirtualKeyboardService.hpp new file mode 100644 index 00000000..a9e60b5d --- /dev/null +++ b/bpstoqml/src/VirtualKeyboardService.hpp @@ -0,0 +1,53 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#ifndef VIRTUALKEYBOARDSERVICE_H_ +#define VIRTUALKEYBOARDSERVICE_H_ + +#include "BlackBerryPlatformService.hpp" + +namespace bb { +namespace cascades { +namespace bps { + +/** + * Class that deals with virtual keyboard events. + * Emitting visible, hidden or info events where the qml + * logic deals with each event appropriately. + */ +class VirtualKeyboardService : public BlackBerryPlatformService { + Q_OBJECT + +public: + VirtualKeyboardService(QObject *parent = 0); + ~VirtualKeyboardService(); + + virtual void requestEvents(); + virtual int eventDomain(); + virtual void handleEvent(bps_event_t *event); + +Q_SIGNALS: + void keyboardVisible(); + void keyboardHidden(); + void keyboardInfo(int height); +}; + +} /* namespace bps */ +} /* namespace cascades */ +} /* namespace bb */ + +QML_DECLARE_TYPE(bb::cascades::bps::VirtualKeyboardService) + +#endif /* VIRTUALKEYBOARDSERVICE_H_ */ diff --git a/bpstoqml/src/smartsignals.cpp b/bpstoqml/src/smartsignals.cpp new file mode 100644 index 00000000..928b52ea --- /dev/null +++ b/bpstoqml/src/smartsignals.cpp @@ -0,0 +1,62 @@ +/* Copyright (c) 2012-2013 Research In Motion Limited. +* +* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +* +* 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. +*/ + +#include "AccelerometerService.hpp" +#include "AzimuthPitchRollService.hpp" +#include "BPSMonitor.hpp" +#include "GeolocationService.hpp" +#include "LightService.hpp" +#include "MagnetometerService.hpp" +#include "ProximityService.hpp" +#include "SmartSignalsApp.hpp" +#include "VirtualKeyboardService.hpp" + +#include +#include + +#include +#include +#include + +using ::bb::cascades::Application; + +Q_DECL_EXPORT int main(int argc, char **argv) { + const char *uri = "bb.cascades.bps"; + // Register the required components with qml + qmlRegisterType(uri, 1, 0, "BPSMonitor"); + qmlRegisterInterface("BlackBerryPlatformService"); + qmlRegisterType(uri, 1, 0, "VirtualKeyboardService"); + qmlRegisterType(uri, 1, 0, "GeolocationService"); + qRegisterMetaType("SensorAccuracy"); + qmlRegisterType(uri, 1, 0, "AccelerometerService"); + qmlRegisterType(uri, 1, 0, "MagnetometerService"); + qmlRegisterType(uri, 1, 0, "ProximityService"); + qmlRegisterType(uri, 1, 0, "AzimuthPitchRollService"); + qmlRegisterType(uri, 1, 0, "LightService"); + + Application app(argc, argv); + + // localization support + QTranslator translator; + QString locale_string = QLocale().name(); + QString filename = QString("SmartSignals_%1").arg(locale_string); + if (translator.load(filename, "app/native/qm")) { + app.installTranslator(&translator); + } + + SmartSignalsApp mainApp; + + return Application::exec(); +} diff --git a/bpstoqml/translations/Makefile b/bpstoqml/translations/Makefile new file mode 100644 index 00000000..08e17888 --- /dev/null +++ b/bpstoqml/translations/Makefile @@ -0,0 +1,12 @@ +QMAKE_TARGET = bpstoqml +LUPDATE = $(QNX_HOST)/usr/bin/lupdate +LRELEASE = $(QNX_HOST)/usr/bin/lrelease + +update: $(QMAKE_TARGET).pro FORCE + $(LUPDATE) $(QMAKE_TARGET).pro + +release: $(QMAKE_TARGET).pro $(QMAKE_TARGET).ts + $(LRELEASE) $(QMAKE_TARGET).pro + +FORCE: + diff --git a/bpstoqml/translations/bpstoqml.pro b/bpstoqml/translations/bpstoqml.pro new file mode 100644 index 00000000..cbc007f5 --- /dev/null +++ b/bpstoqml/translations/bpstoqml.pro @@ -0,0 +1 @@ +include (../bpstoqml.pro) diff --git a/docs/bbmcontacts.qdoc b/docs/bbmcontacts.qdoc new file mode 100644 index 00000000..5b32f872 --- /dev/null +++ b/docs/bbmcontacts.qdoc @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Research In Motion Limited. +** All rights reserved. +** Contact: Research In Motion Ltd. (http://www.rim.com/company/contact/) +** +** This file is part of the examples of the BB10 Platform. +** +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Research In Motion Limited. +** +****************************************************************************/ + +/*! + \page bbmcontacts + \example bbmcontacts + \title BBM Contacts Example + + \section1 Description + + The BBM Contacts example demonstrates how to retrieve your + list of contacts(that have the same application installed) from the BBM Social Platform. + + \image bbmcontacts-example.png + \image bbmcontacts-example1.png + + \section1 Overview + In this example we'll learn how to use the \c ContactService class of the bb::platform::bbm + module to retrieve your contacs, that have the same application installed, from the BBM Social Platform. + + To use the BBM Social Platform, the application must register first. How this is done is explained + in \l{bbmregistration} and this sample is based on that code. + We will describe here everything that needs to be done after the registration was successful. + + The business logic of this application is encapsulated in the \c ContactsDisplay class, and the + Contact class, which is exposed to QML as a metatype. + + \section1 UI + The main UI of this application is shown after a successful registration. + + \section2 The Contacts display page + + \snippet bbmcontacts/assets/ContactList.qml 0 + + It consists of one page with a single field to display a single value of + the number of contacts found to have your application installed. + + \snippet bbmcontacts/assets/ContactList.qml 1 + + Following this field is the \c ListView containing those contacts. Whenever the user + triggers one of the ContactItem's, an instance of the ContactPage page is + created through a \c ComponentDefinition and pushed on the navigation pane. + + \snippet bbmcontacts/assets/ContactList.qml 2 + + The list items are represented by custom ListItemComponent called ContactItem. Which consists + of two labels to display the Contact's brief summary (display name, personal message), and his/her avatar in + a LeftToRight order. + + \snippet bbmcontacts/assets/ContactItem.qml 0 + + \section2 The Contact Page + + \snippet bbmcontacts/assets/ContactPage.qml 0 + + At the top an \c ImageView is located to show the Contact avatar. + The image is provided through the 'avatar' property of the \c Contact object + and uses a placeholder image by default. Only when the call to the ContactService::requestDisplayPicture() method + is successful, the real avatar image replaces the placeholder image in the property. + + \snippet bbmcontacts/assets/ContactPage.qml 1 + + Below the avatar, an \c ImageView and a \c Label are located that show the current busy status + and the name of the \c Contact. Depending on the value of the Contact's 'busy' property, the busy indicator + is visible or hidden. + + \snippet bbmcontacts/assets/ContactPage.qml 2 + + For all the other data of the \c Contact, a Field is created, which is a custom component (implemented in Field.qml) + with two \c{Label}s side by side. The left \c Label displays the title of the field and the right \c Label the + corresponding value. All the Contact data are provided by \c Contact through properties, which we simply bind + against the Field's 'value' property. + + \section1 The Contact class + The \c Contact class encapsulates the information about the users contact and makes the data available through + properties. + + \snippet bbmcontacts/src/Contact.hpp 0 + + Inside the constructor the member variables are initialized. + + \snippet bbmcontacts/src/Contact.cpp 0 + + Whenever the \c ContactsDisplay class creates or updates a Contact instance in the ListView model the requestDisplayPicture() + method is invoked, this in turn updates the Contact avatar image. This is the result of having the displayPictureUpdate signal + of the ContactService object connected to our own avatarUpdated slot, so that whenever the contact changes we retrieve it's + image right away. + Inside this method we verify that the avatarUpdate is for this Contact using handle comparison, afterwards we take the raw image + data that is provided, create an \c Image object from it, since \c ImageView can only use that one as input, and emit the change + notification signal to let the \c ImageView update its representation. + + \snippet bbmcontacts/src/Contact.cpp 2 + + In all the other property accessor methods, we simply return the values as we get them from the \c bb::platform::bbm::Contact object. + + \snippet bbmcontacts/src/Contact.cpp 1 + + \section1 The ContactsDisplay class + The \c ContactsDisplay class encapsulates the code that populates and updates the user contact list in the ListView. + + \snippet bbmcontacts/src/ContactsDisplay.hpp 0 + + The class takes a reference to the \c Context object in the constructor, that instance is used later to create the ContactService. + Additionally it provides three slots to create the ContactList.qml UI, update ListView model, and update a single contact. + + \snippet bbmcontacts/src/ContactsDisplay.cpp 0 + + Inside the constructor we just initialize the member variable. + + After a successful registration to the BBM service, the show() slot of the \c ContactsDisplay class is invoked. The + signal/slot connection for this is established in main.cpp + + \snippet bbmcontacts/src/main.cpp 0 + + Inside the show() slot a new \c ContactService object is created using the supplied \c Context. This does the low-level communication with + the BBM service. We connect all update signals of the \c ContactService object to our own update slots, so that + our DataModel notify modifications as soon as any underlying \c Contact object is added or changed. We than retrieve the number of + bbm contacts that have this application installed, update the qml field with this value and populate the QListDataModel with the Contact's. + + At the end of this method, the UI is loaded from ContactList.qml + + \snippet bbmcontacts/src/ContactsDisplay.cpp 1 + + The updateModel() method retrieves a list of Contact's, that have your application installed, using the ContactService. Afterwards, + it creates a Contact instance for each one of them and connects the displayPictureUpdated signal to our avatarUpdated slot + in order to receive the contact display image when requestDisplayPicture() is made via ContactService. + + \snippet bbmcontacts/src/ContactsDisplay.cpp 1 + + The contactUpdated() method searches through the ListView data model to find the Contact with the specified handle, once it is found + it is replaced with the new Contact instance and the appropriate connections are made in order to get the contact display image + update. +*/ diff --git a/docs/bpstoqml.qdoc b/docs/bpstoqml.qdoc new file mode 100644 index 00000000..d9fab174 --- /dev/null +++ b/docs/bpstoqml.qdoc @@ -0,0 +1,206 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Research In Motion Limited. +** All rights reserved. +** Contact: Research In Motion Ltd. (http://www.rim.com/company/contact/) +** +** This file is part of the examples of the BB10 Platform. +** +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Research In Motion Limited. +** +****************************************************************************/ + +/*! + \page bpstoqml + \example bpstoqml + \title Bps to qml Example + + \section1 Description + + The Bps to qml example demonstrates how to expose bps events to qml, by requesting + events for various modules that you want to listen in on and emitting module specific + signals when the event arrives in order to notify the qml context of it. This allows + the qml side decide how it wants to act based on the data provided by the signal; this, + more closely follows the MVC pattern of design. + + \image bpstoqml-example.png + \image bpstoqml-example1.png + + \section1 Overview + + In this example we'll learn how to use the Bps api to register and request BPS events + of the specified domain on the current thread. As a side effect, we will learn + how to read the various sensors that are available to us using the Bps api as well. + The various modules are registered as types with the qml, once we import the package that + they are registered under, we can use them in the same manner as the core qml elements without + any distinction distinction. + + \section1 The UI + The UI of this sample application consists of \c Images depicting the background scene (hilltops, sky, etc), + custom components such as, allert sign and status bar for visual communication of events and + custom buttons in the shape of clouds. + + \section2 The main page + After startup the main page (implemented in main.qml) is shown, which contains a variety of + custom components to represent the various Bps events. + + \snippet bpstoqml/assets/main.qml 0 + + The BPSMonitor component initializes the BlackBerry Platform Services (BPS), it is written in + c++ and registers the various sensors for which we would like to receive events for. In order + to receive events it initializes BPSEventHandler which subclasses \c AbstractBpsEventHandler that + allows us to receive the Bps events. + + \snippet bpstoqml/assets/main.qml 1 + + This is the custom component that represents the azimuth,pitch and roll sensor, allowing us to act upon + receiving the bps events in regard to this sensor. This custom component manipulates the cloud buttons + by adjusting their rotationZ property for each azimuth, roll, pitch value. + + \snippet bpstoqml/assets/main.qml 2 + + The LightService component, as the name implies, generates signals from Bps events with illuminance values, which + we in turn use to change the allert sign \c Container opacity property. + + \snippet bpstoqml/assets/main.qml 3 + + The VirtualKeyboardService listens for keyboard visible and hidden bps events, once an event happens it notifies + the qml context via the onKeyboardVisible and onKeyboardHidden signals. This in turn changes the status bar + position by positioning it to the new coordinate along the y axis. + + \snippet bpstoqml/assets/main.qml 4 + + The GeolocationService component notifies the user with location info by updating the status bar with latitude/longitude + coordinates when the location service is activated and GEOLOCATION_INFO Bps events are received. + + \snippet bpstoqml/assets/main.qml 5 + + The ProximityService component initializes the proximity sensor, and waits on proximity readings via the bps events. Upon + receiving proximity readings it provides the qml context with proximity data by generating onProximityData signals. + In turn we change the status bar with a meaningful message depending on the reading we get. + + \snippet bpstoqml/assets/main.qml 6 + + The AlertSign component is used as a visual indicator that the Azimuth button has been pressed in order to activate(visible) sign, and + by pressing the Pitch button the sign is deactivated(hidden). It's also used to indicate light sensor value by changing the components + opacity property value. + + \snippet bpstoqml/assets/main.qml 7 + + These are the custom buttons represented as clouds, each one changes the status bar to it's name in order to differentiate which one was pressed + , also some will have special functions like enabling or disabling the alert sign visibility. The animations of the buttons are created by + changing their rotationZ property in accordance with the AzimuthPitchRollService sensor values. + + \snippet bpstoqml/assets/main.qml 8 + + This is the StatusBar custom component that is used by the other custom components/sensors to relay information back to the user such as, + which button has been pressed, the proximity data or even geolocation latitude/longitude coordinates. + + + \section1 The BPSMonitor class + The \c BPSMonitor class is the central class in this application. It initializes \c BPSEventHandler, which creates the bridge between + Bps events and the various sensor components, this allows for the components to act upon the events and generate signals to + inform the qml context, which in turn allows us to wow you with animations. + + \snippet bpstoqml/src/BPSMonitor.hpp 0 + + Inside the constructor the other business logic objects are instantiated, the most important being the BPSEventHandler, which + is responsible for propegating the bps events to all the sensor components that are listening on them and generating signals + based on the event data. + + \snippet bpstoqml/src/BPSMonitor.cpp 0 + + In all the other property accessor methods, we simply set or return the different \c BlackBerryPlatformService components, which + represent the various sensors. + + \snippet bpstoqml/src/BPSMonitor.cpp 1 + + \section1 The BPSEventHandler class + The \c BPSEventHandler class contains the business logic for tracking the instantiaded \c BlackBerryPlatformService, subscribing + the sensor domain with the bps event framework and propegating the Bps events to the individual services for further processing. + + \snippet bpstoqml/src/BPSEventHandler.hpp 0 + + The registerService() method adds the \c BlackBerryPlatformService to the list and quries for it's service domain in order to + register it for receiving BPS events of the specified domain on the current thread. + + \snippet bpstoqml/src/BPSEventHandler.cpp 0 + + The event() method is an implementation of the parent \c AbstractBpsEventHandler::event() method, which receives the Bps event's when + the services domain has been registered and a request for it's events has been made. Upon receiving the event it propegates that event + for further processing to the \c BlackBerryPlatformService. + + \snippet bpstoqml/src/BPSEventHandler.cpp 1 + + \section1 The BlackBerryPlatformService class + + The \c BlackBerryPlatformService abstract class(interface) defines the sensor classes common functionality. Leaving them to define + handleEvent() behaviour only. + + \snippet bpstoqml/src/BlackBerryPlatformService.hpp 0 + + \section1 The AbstractSensorService class + + The \c AbstractSensorService class amalgamates the common functionality accross the different services. Defining their functionality + as to provide the same behaviour(methods) for all the services that subcalls this class. + + \snippet bpstoqml/src/AbstractSensorService.hpp 0 + + The constructor initializes all the member variables, one being the sensor type which describes the custom sensor component it represents. + + \snippet bpstoqml/src/AbstractSensorService.cpp 0 + + The following methods represent the common functionality accross the various sensor service components such as, enabling callibration, + running in the background, setting the sensor rate or retrieving that sensors domain, which is important in order to subscribe the service + for receiving bps events. + + \snippet bpstoqml/src/AbstractSensorService.cpp 1 + + The requestEvents() method enables/disables the various settings, that were mentioned above (callibration, data rate, etc), using bps api + before making the request to bps for specific domain events. + bu + \snippet bpstoqml/src/AbstractSensorService.cpp 2 + + The following are utility(helper) methods to simplify in generating a timestamp for an event, or by retrieving and mapping the bps sensor accuracy + enum values to the enum values defined for use in the qml context. + + \snippet bpstoqml/src/AbstractSensorService.cpp 3 + + \section1 The Sensor Service classes + + The sensor services such as, \c AccelerometerService, \c VirtualKeyboardService, etc, deal with implementing the BlackBerryPlatformService::handleEvent() + method only. The rest of the common methods have been implemented by \c AbstractSensorService which the services subclass and hence inherit from. + Meaning, each of the service classes implements the business logic for dealing with Bps events of the specific service sensor type (i.e. SENSOR_TYPE_ACCELEROMETER). + + Let's take a look at \c AccelerometerService as an example. + + \snippet bpstoqml/src/AccelerometerService.hpp 0 + + The constructor for these services typically initializes its member variables and most importantly sets the sensor type that it is representing. + Many of the Bps functions that are invoked depend on this type in order to achieve the result that is tied to the specific + sensor it represents. + + \snippet bpstoqml/src/AccelerometerService.cpp 0 + + The handleEvent() method contains all the business logic for dealing with the sensor specific event, disseminating its data and emitting a + signal with the pieces of data that you want to expose to the qml context. + + \snippet bpstoqml/src/AccelerometerService.cpp 1 + + The above mentioned service structure, using AccelerometerService as an example is used accross all the various sensor service classes + implemented in this sample. The reason this is simplified is because the functional commonality has been implemented in the + \c AbstractSensorService class which all these services subclass and hence inherit this functionality by default. + + The only exception is the GeolocationService which only inherits from BlackBerryPlatformService, because it uses a different api lib other + than the core bps sensor api; hence, the common methods like eventDomain(), requestEvents(), etc, have to be re-implemented using that libraries + specific api calls. +*/ diff --git a/docs/imageloader.qdoc b/docs/imageloader.qdoc index c3a6cdd1..c3d36911 100644 --- a/docs/imageloader.qdoc +++ b/docs/imageloader.qdoc @@ -32,7 +32,7 @@ \image imageloader-example.png \section1 Overview - In this example we'll learn how to use \c QNetworkAccessManager and \c QThread to download + In this example we'll learn how to use \c QNetworkAccessManager and QtConcurrent to download an image file asynchronously from the network and then offload the time-consuming task of converting the raw data into a QImage and scaling it down to a proper size into a separated worker thread. @@ -89,7 +89,7 @@ the final image data through the 'image' property. To download the image the \c QNetworkAccessManager class is used and afterwards the raw image data - are converted and scaled inside a thread. Thread contexts are represented by the \c QThread class. + are converted and scaled inside a thread. Thread contexts are associated with the \c QFuture class. \snippet imageloader/src/imageloader.hpp 0 @@ -97,11 +97,6 @@ \snippet imageloader/src/imageloader.cpp 0 - Inside the destructor we check whether the worker thread still exists. If that's the case, we - wait for it to finish execution. - - \snippet imageloader/src/imageloader.cpp 1 - The load() method is called to start the download operation. Inside this method we first change the value of the 'loading' property to signal that we have started our work. Afterwards the \c QNetworkAccessManager object is created and a GET request with the image URL is issued. @@ -118,20 +113,16 @@ object and scale it down to a proper size. However since this operation can take a long time, we want to offload it into the worker thread. - So we create a new \c QThread instance and move the \c ImageProcessor object to the worker thread. - Moving a \c QObject based object to a \c QThread means that the object is associated with this thread and - further slot invocations will be executed inside this thread (see \l http://qt-project.org/doc/qt-4.8/threads-qobject.html) + So we create a new \c QFuture instance by calling QtConcurrent::run(), where we pass the \c ImageProcessor reference and + its member function that is to be executed in a separate thread. Afterwards, we assign this QFuture to the QFutureWatcher in + order to monitor thread status indirectly throught the QFuture, that is associated with the thread context, using signals and slots. - The \c QThread object will emit the started() signal once the thread context is set up. We connect this signal - against the start() slot of the \c ImageProcessor object, so that this code will be executed inside the thread context. - When the \c QThread has finished the execution of the thread context, it emits the finished() signal. We connect it - against the \c QThread's own deleteLater() slot, so that it is deleted automatically. + The \c QFutureWatcher object will emit the started() signal once it starts watching the \c QFuture. + When the \c QFuture has finished, meaning the execution of the thread context is done, it emits the finished() signal which + causes the connected method onImageProcessingFinished() to be executed. - When the \c ImageProcessor has finished its work, it emits the finished(QImage) signal. We connect this signal against - two slots. Once against our custom onImageProcessingFinished() slot, where we use the converted and scaled image, and once - against the quit() slot of the \c QThread to trigger its termination. - - In the last step we trigger the start of the \c QThread object. + When the \c ImageProcessor has finished its work, it returns the QImage instance. Which in turn causes a finished() signal to be emited + by the QFutureWatcher, which in turn executes the onImageProcessingFinished method where we use the converted and scaled image. \snippet imageloader/src/imageloader.cpp 3 @@ -146,11 +137,10 @@ \section1 The ImageProcessor class The \c ImageProcessor class encapsulates the conversion of the raw image data into a QImage and the following scaling. Its API is designed to be used inside a thread by providing a start() slot, which - is invoked as a result of the \c{QThread}'s started() signal, and a finished() signal, which is connected - against the \c {QThread}'s quit() slot to stop the event loop inside the thread. + is invoked as a result of the QtConcurrent::run() method. The raw image data are passed in via the constructor and the scaled down \c QImage object is passed back - as parameter of the finished() signal. + as the return value of the start() slot. \snippet imageloader/src/imageprocessor.hpp 0 @@ -166,11 +156,7 @@ In the second step we scale down the image to 768x500 pixels to make them fit inside the \c ListView. - In the last step we emit the finished signal to notify that we are done. + In the last step we return the processed QImage to notify that we are done. \snippet imageloader/src/imageprocessor.cpp 1 - - \bold{Note:} Since signal/slot connections across thread boundaries are no direct method calls (unlike - signal/slot connections in the same thread), but are based on event delivery, passing parameters in the - signal is thread-safe, because a copy of the parameters is created and the copy is sent to the receiver thread. */ diff --git a/docs/images/bbmcontacts-example.png b/docs/images/bbmcontacts-example.png new file mode 100644 index 00000000..48eada06 Binary files /dev/null and b/docs/images/bbmcontacts-example.png differ diff --git a/docs/images/bbmcontacts-example1.png b/docs/images/bbmcontacts-example1.png new file mode 100644 index 00000000..b85cbebb Binary files /dev/null and b/docs/images/bbmcontacts-example1.png differ diff --git a/docs/images/bpstoqml-example.png b/docs/images/bpstoqml-example.png new file mode 100644 index 00000000..4af2e83b Binary files /dev/null and b/docs/images/bpstoqml-example.png differ diff --git a/docs/images/bpstoqml-example1.png b/docs/images/bpstoqml-example1.png new file mode 100644 index 00000000..2124e848 Binary files /dev/null and b/docs/images/bpstoqml-example1.png differ diff --git a/docs/pages.qdoc b/docs/pages.qdoc index d36f7686..f79b52e0 100644 --- a/docs/pages.qdoc +++ b/docs/pages.qdoc @@ -40,6 +40,7 @@ \o \l{dialogs}{Dialogs} \o \l{notifications}{Notifications} \o \l{paymentservice}{Payment Service} + \o \l{bpstoqml}{BPS to QML} \endlist \o \bold {Device and Communication} \list @@ -69,6 +70,7 @@ \o \l{bbmprofile}{BBM Profile} \o \l{bbmprofilebox}{BBM Profile Box} \o \l{bbmregistration}{BBM Registration} + \o \l{bbmcontacts}{BBM Contacts} \o \l{invokeclient}{Invoke Client} \o \l{invoketarget}{Invoke Target} \o \l{socialinvocation}{Social Invocation} diff --git a/imageloader/src/imageloader.cpp b/imageloader/src/imageloader.cpp index a2707b8f..c28d1195 100644 --- a/imageloader/src/imageloader.cpp +++ b/imageloader/src/imageloader.cpp @@ -47,11 +47,7 @@ ImageLoader::ImageLoader(const QString &imageUrl, QObject* parent) * Destructor */ //! [1] -ImageLoader::~ImageLoader() -{ - if (m_thread) - m_thread->wait(); -} +ImageLoader::~ImageLoader() { } //! [1] /** @@ -98,29 +94,15 @@ void ImageLoader::onReplyFinished() // Setup the image processing thread ImageProcessor *imageProcessor = new ImageProcessor(data); - m_thread = new QThread(this); - - // Move the image processor to the worker thread - imageProcessor->moveToThread(m_thread); - - // Invoke ImageProcessor's start() slot as soon as the worker thread has started - connect(m_thread, SIGNAL(started()), imageProcessor, SLOT(start())); - // Delete the worker thread automatically after it has finished - connect(m_thread, SIGNAL(finished()), m_thread, SLOT(deleteLater())); + QFuture future = QtConcurrent::run(imageProcessor, &ImageProcessor::start); - /* - * Invoke our onProcessingFinished slot after the processing has finished. - * Since imageProcessor and 'this' are located in different threads we use 'QueuedConnection' to - * allow a cross-thread boundary invocation. In this case the QImage parameter is copied in a thread-safe way - * from the worker thread to the main thread. - */ - connect(imageProcessor, SIGNAL(finished(QImage)), this, SLOT(onImageProcessingFinished(QImage)), Qt::QueuedConnection); + // Invoke our onProcessingFinished slot after the processing has finished. + connect(&m_watcher, SIGNAL(finished()), this, SLOT(onImageProcessingFinished())); - // Terminate the thread after the processing has finished - connect(imageProcessor, SIGNAL(finished(QImage)), m_thread, SLOT(quit())); + // starts watching the given future + m_watcher.setFuture(future); - m_thread->start(); } } else { m_label = tr("Error: %1 status: %2").arg(reply->errorString(), reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString()); @@ -142,14 +124,14 @@ void ImageLoader::onReplyFinished() //! [3] /** - * ImageLoader::onImageProcessingFinished(const QImage&) + * ImageLoader::onImageProcessingFinished() * * Handler for the signal indicating the result of the image processing. */ //! [4] -void ImageLoader::onImageProcessingFinished(const QImage &image) +void ImageLoader::onImageProcessingFinished() { - const QImage swappedImage = image.rgbSwapped(); + const QImage swappedImage = m_watcher.future().result().rgbSwapped(); const bb::ImageData imageData = bb::ImageData::fromPixels(swappedImage.bits(), bb::PixelFormat::RGBX, swappedImage.width(), swappedImage.height(), swappedImage.bytesPerLine()); m_image = bb::cascades::Image(imageData); diff --git a/imageloader/src/imageloader.hpp b/imageloader/src/imageloader.hpp index 084de7ca..b70b159e 100644 --- a/imageloader/src/imageloader.hpp +++ b/imageloader/src/imageloader.hpp @@ -68,7 +68,7 @@ private Q_SLOTS: /* * Response handler for the image process operation. */ - void onImageProcessingFinished(const QImage &image); + void onImageProcessingFinished(); private: // The accessor methods of the properties @@ -84,8 +84,8 @@ private Q_SLOTS: // The URL of the image that should be loaded QString m_imageUrl; - // The thread context that processes the image - QPointer m_thread; + // The thread status watcher + QFutureWatcher m_watcher; }; //! [0] diff --git a/imageloader/src/imageprocessor.cpp b/imageloader/src/imageprocessor.cpp index 1c87a3cc..1ee921d0 100644 --- a/imageloader/src/imageprocessor.cpp +++ b/imageloader/src/imageprocessor.cpp @@ -24,7 +24,7 @@ ImageProcessor::ImageProcessor(const QByteArray &imageData, QObject *parent) //! [0] //! [1] -void ImageProcessor::start() +QImage ImageProcessor::start() { QImage image; @@ -34,6 +34,6 @@ void ImageProcessor::start() // Image processing goes here, example could be adding water mark to the downloaded image - emit finished(image); + return image; } //! [1] diff --git a/imageloader/src/imageprocessor.hpp b/imageloader/src/imageprocessor.hpp index 0e1746f3..2ca8a6c3 100644 --- a/imageloader/src/imageprocessor.hpp +++ b/imageloader/src/imageprocessor.hpp @@ -44,15 +44,7 @@ public Q_SLOTS: /* * Starts the actual operation. */ - void start(); - -Q_SIGNALS: - /* - * This signal is emitted after the operation has finished. - * - * @param image The processed image. - */ - void finished(const QImage &image); + QImage start(); private: // The raw image data diff --git a/messages/bar-descriptor.xml b/messages/bar-descriptor.xml index dc82a2d2..75027133 100644 --- a/messages/bar-descriptor.xml +++ b/messages/bar-descriptor.xml @@ -100,6 +100,7 @@ run_native access_pimdomain_messages + access_sms_mms