Merge lp:~renatofilho/address-book-app/new-bottom-edge into lp:address-book-app

Proposed by Renato Araujo Oliveira Filho
Status: Superseded
Proposed branch: lp:~renatofilho/address-book-app/new-bottom-edge
Merge into: lp:address-book-app
Diff against target: 2077 lines (+541/-660)
31 files modified
src/imports/ABContactEditorPage.qml (+8/-5)
src/imports/ABContactListPage.qml (+161/-166)
src/imports/ABContactViewPage.qml (+31/-3)
src/imports/ABNewContactBottomEdge.qml (+67/-0)
src/imports/BottomEdge.qml (+0/-321)
src/imports/BottomEdgeShadow.qml (+0/-31)
src/imports/CMakeLists.txt (+1/-2)
src/imports/MainWindow.qml (+29/-1)
src/imports/Settings/SettingsPage.qml (+54/-3)
src/imports/Ubuntu/AddressBook/Base/ContactDetailBase.qml (+20/-5)
src/imports/Ubuntu/AddressBook/Base/ContactDetailGroupBase.qml (+2/-1)
src/imports/Ubuntu/AddressBook/Base/RemoveContactsDialog.qml (+19/-2)
src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml (+1/-0)
src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailGroupWithTypeEditor.qml (+12/-23)
src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml (+1/-0)
src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml (+8/-3)
src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailWithTypeEditor.qml (+0/-1)
src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml (+25/-17)
src/imports/Ubuntu/AddressBook/ContactEditor/TextInputDetail.qml (+24/-10)
src/imports/Ubuntu/AddressBook/ContactView/ActionButton.qml (+1/-0)
src/imports/Ubuntu/AddressBook/ContactView/BasicFieldView.qml (+2/-0)
src/imports/Ubuntu/AddressBook/ContactView/ContactDetailAvatarView.qml (+2/-0)
src/imports/Ubuntu/AddressBook/ContactView/ContactDetailGroupWithTypeView.qml (+13/-21)
src/imports/Ubuntu/AddressBook/ContactView/ContactDetailNameView.qml (+2/-1)
src/imports/Ubuntu/AddressBook/ContactView/ContactDetailSyncTargetView.qml (+2/-1)
src/imports/Ubuntu/AddressBook/ContactView/ContactDetailWithTypeView.qml (+4/-0)
src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml (+1/-0)
src/imports/Ubuntu/Contacts/ContactDelegate.qml (+1/-0)
src/imports/Ubuntu/Contacts/ContactListView.qml (+41/-19)
src/imports/Ubuntu/Contacts/ContactSimpleListView.qml (+6/-13)
src/imports/Ubuntu/Contacts/FastScroll.qml (+3/-11)
To merge this branch: bzr merge lp:~renatofilho/address-book-app/new-bottom-edge
Reviewer Review Type Date Requested Status
Ubuntu Phablet Team Pending
Review via email: mp+279612@code.launchpad.net

This proposal has been superseded by a proposal from 2015-12-04.

Commit message

Implement the new bottom edge using the SDK component.

To post a comment you must log in.
548. By Renato Araujo Oliveira Filho

Update BottomEdge editor page with the correct contact model.

549. By Renato Araujo Oliveira Filho

Removed support for deprecated application arguments.

550. By Renato Araujo Oliveira Filho

Make use of the new SDK PageHearder API.

551. By Renato Araujo Oliveira Filho

WORKAROUND: Set 'QuickUtils.mouseAttached = true' to avoid problems with bottom edge on desktop;

552. By Renato Araujo Oliveira Filho

Make sure that a contact is selected on application startup.

553. By Renato Araujo Oliveira Filho

Push contact view page component instead of object to avoid problems with page stack.

554. By Renato Araujo Oliveira Filho

Make bottom edge component on contact view available only when in dual column layout.

555. By Renato Araujo Oliveira Filho

Does not use navigationActions.

556. By Renato Araujo Oliveira Filho

Trunk merged.

557. By Renato Araujo Oliveira Filho

Fix problems with previous merge.

558. By Renato Araujo Oliveira Filho

Remove debug message.
Fix focus on contact list after close contact editor page.
Fix ambigous 'esc' short cut when editor page is opened.

559. By Renato Araujo Oliveira Filho

Create a empty state page for multi column layout.

560. By Renato Araujo Oliveira Filho

Move focus back to contaclist after close ContactEditor page.
Add 'esc' shortcut to close BottomEdge.

561. By Renato Araujo Oliveira Filho

Change bottom edge visual if a mouse is present.

562. By Renato Araujo Oliveira Filho

Update test to use new header API.

563. By Renato Araujo Oliveira Filho

Trunk merged.

564. By Renato Araujo Oliveira Filho

Create a leading actions property on Contact editor page to avoid problems with SDK replacing it.
Check if the mouse event is a real mouse event and not a touch event.

565. By Renato Araujo Oliveira Filho

Only enable keyboard visuals after pres 'down' key. To avoid enabling it while using the virtual keyboard.

566. By Renato Araujo Oliveira Filho

Sync load bottom edge page.

567. By Renato Araujo Oliveira Filho

Load BottomEdge component async to avoid delays on app startup.
Fix bottom edge contents size.

568. By Renato Araujo Oliveira Filho

Does not move contact list when vkb appears on bottom edge page.

569. By Renato Araujo Oliveira Filho

Trunk merged.

570. By Renato Araujo Oliveira Filho

Fixed 'back' action state while searching.

571. By Renato Araujo Oliveira Filho

Compile ContactEditorPage before push it on stack.

572. By Renato Araujo Oliveira Filho

Avoid stole contact list focus while creating bottom edge component.

573. By Renato Araujo Oliveira Filho

Disable edit button after first click on it. (avoid push the page more than once)

574. By Renato Araujo Oliveira Filho

highlight contact on click.

575. By Renato Araujo Oliveira Filho

Quick focus on contact name after open bottom edge page.

576. By Renato Araujo Oliveira Filho

Does not highlight settings item if not using keyboard.

577. By Renato Araujo Oliveira Filho

Update autopilot tests to work with the new bottom edge component.

578. By Renato Araujo Oliveira Filho

Removed debug message.

579. By Renato Araujo Oliveira Filho

Disable bottom edge while searching on multi colum layout.

580. By Renato Araujo Oliveira Filho

Cancel search after open bottom edge.

581. By Renato Araujo Oliveira Filho

Update contact view title on contact name change.

582. By Renato Araujo Oliveira Filho

Removed debug message.

583. By Renato Araujo Oliveira Filho

Fetch selected contact on application expansion.

584. By Renato Araujo Oliveira Filho

Use unity 8 private api to detect mouse and keyboard.

585. By Renato Araujo Oliveira Filho

Fetch first contact if no contact is selected after close bottom edge.

586. By Renato Araujo Oliveira Filho

Fixed field focus while adding new fields on contact editor.

587. By Renato Araujo Oliveira Filho

Disable bottom edge shortcut on contact list while it is not active.

588. By Renato Araujo Oliveira Filho

Update autopilot tests to work with the new bottom edge components.

589. By Renato Araujo Oliveira Filho

Update contact delegate click animation.

590. By Renato Araujo Oliveira Filho

Remove unused variables.

591. By Renato Araujo Oliveira Filho

Fixed focus on wrong field after add a new contact detail

592. By Renato Araujo Oliveira Filho

Focus contact list after close bottom edge.

593. By Renato Araujo Oliveira Filho

set minimum width and height for the app.

594. By Renato Araujo Oliveira Filho

Fixed focus on contact deletion.

595. By Renato Araujo Oliveira Filho

Fixed share component page to work with pagestack

596. By Renato Araujo Oliveira Filho

Reduce the application width necessary to change into multi column layout.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/imports/ABContactEditorPage.qml'
--- src/imports/ABContactEditorPage.qml 2015-10-26 13:18:11 +0000
+++ src/imports/ABContactEditorPage.qml 2015-12-04 15:09:43 +0000
@@ -34,10 +34,10 @@
34 name: "cancel"34 name: "cancel"
3535
36 text: i18n.tr("Cancel")36 text: i18n.tr("Cancel")
37 iconName: "back"37 iconName: "down"
38 onTriggered: {38 enabled: root.active && root.enabled
39 root.cancel()39 shortcut: "Esc"
40 }40 onTriggered: root.cancel()
41 }41 }
4242
43 head.actions: [43 head.actions: [
@@ -46,9 +46,10 @@
46 name: "save"46 name: "save"
4747
48 text: i18n.tr("Save")48 text: i18n.tr("Save")
49 shortcut: "Ctrl+s"
49 iconName: "ok"50 iconName: "ok"
50 // disable save button while avatar scale still running51 // disable save button while avatar scale still running
51 enabled: root.isContactValid52 enabled: root.isContactValid && root.active
52 onTriggered: root.save()53 onTriggered: root.save()
53 }54 }
54 ]55 ]
@@ -58,4 +59,6 @@
58 pageStack.contactListPage.moveListToContact(contact)59 pageStack.contactListPage.moveListToContact(contact)
59 }60 }
60 }61 }
62
63 Component.onDestruction: console.debug("Destroy editor")
61}64}
6265
=== modified file 'src/imports/ABContactListPage.qml'
--- src/imports/ABContactListPage.qml 2015-11-25 16:59:11 +0000
+++ src/imports/ABContactListPage.qml 2015-12-04 15:09:43 +0000
@@ -1,4 +1,4 @@
1/*1/*
2 * Copyright (C) 2012-2015 Canonical, Ltd.2 * Copyright (C) 2012-2015 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
@@ -30,18 +30,19 @@
30 id: mainPage30 id: mainPage
31 objectName: "contactListPage"31 objectName: "contactListPage"
3232
33 property var viewPage: null
33 property bool pickMode: false34 property bool pickMode: false
34 property alias contentHubTransfer: contactExporter.activeTransfer35 property alias contentHubTransfer: contactExporter.activeTransfer
35 property bool pickMultipleContacts: false36 property bool pickMultipleContacts: false
36 property QtObject contactIndex: null37 property QtObject contactIndex: null
37 property string newPhoneToAdd: ""38 property string newPhoneToAdd: ""
38 property alias contactManager: contactList.manager39 property alias contactManager: contactList.manager
39 property Page contactViewPage: null
40 property Page contactEditorPage: null
41 property var _busyDialog: null40 property var _busyDialog: null
42 property bool _importingTestData: false41 property bool _importingTestData: false
42 property bool _creatingContact: false
4343
44 readonly property bool bottomEdgePageOpened: bottomEdge.opened && bottomEdge.fullLoaded44 readonly property string currentViewContactId: viewPage && viewPage.contact ? viewPage.contact.contactId : ""
45 readonly property bool bottomEdgePageOpened: false //bottomEdge.opened && bottomEdge.fullLoaded
45 readonly property bool isEmpty: (contactList.count === 0)46 readonly property bool isEmpty: (contactList.count === 0)
46 readonly property bool allowToQuit: (application.callbackApplication.length > 0)47 readonly property bool allowToQuit: (application.callbackApplication.length > 0)
47 readonly property var contactModel: contactList.listModel ? contactList.listModel : null48 readonly property var contactModel: contactList.listModel ? contactList.listModel : null
@@ -61,30 +62,31 @@
61 function createContactWithPhoneNumber(phoneNumber)62 function createContactWithPhoneNumber(phoneNumber)
62 {63 {
63 var newContact = ContactsJS.createEmptyContact(phoneNumber, mainPage);64 var newContact = ContactsJS.createEmptyContact(phoneNumber, mainPage);
64 openEditPage({model: contactList.listModel,65 pageStack.bottomEdge.editContact(newContact, mainPage.contactModel)
65 contact: newContact,
66 initialFocusSection: "name"},
67 mainPage);
68 }
69
70 function openEditPage(editPageProperties, sourcePage) {
71 var component = Qt.createComponent(Qt.resolvedUrl("ABContactEditorPage.qml"))
72 if (component.status === Component.Ready) {
73 mainPage.contactEditorPage = component.createObject(mainPage, editPageProperties)
74 pageStack.addPageToNextColumn(sourcePage, mainPage.contactEditorPage)
75 }
76 }66 }
7767
78 function openViewPage(viewPageProperties) {68 function openViewPage(viewPageProperties) {
69 if (mainPage.viewPage) {
70 pageStack.removePages(mainPage.viewPage)
71 mainPage.viewPage.destroy()
72 mainPage.viewPage = null
73 }
74
79 var component = Qt.createComponent(Qt.resolvedUrl("ABContactViewPage.qml"))75 var component = Qt.createComponent(Qt.resolvedUrl("ABContactViewPage.qml"))
80 if (component.status === Component.Ready) {76 if (component.status === Component.Ready) {
81 mainPage.contactViewPage = component.createObject(mainPage, viewPageProperties)77 mainPage.viewPage = component.createObject(mainPage, viewPageProperties)
82 pageStack.addPageToNextColumn(mainPage, mainPage.contactViewPage)78 pageStack.addPageToNextColumn(mainPage, mainPage.viewPage)
83 }79 }
84 }80 }
8581
86 function showContact(contact)82 function showContact(contact)
87 {83 {
84 var currentContact = contactList.listModel.contacts[contactList.currentIndex]
85 if (currentContact && (mainPage.currentViewContactId === currentContact.contactId)) {
86 console.debug("Skip show contact")
87 return
88 }
89
88 // go back to normal state if not searching90 // go back to normal state if not searching
89 if ((state !== "searching") &&91 if ((state !== "searching") &&
90 (state !== "vcardImported")) {92 (state !== "vcardImported")) {
@@ -136,14 +138,12 @@
136138
137 function moveListToContact(contact)139 function moveListToContact(contact)
138 {140 {
139 // skipt it if searching or importing contacts141 if ((state !== "searching") &&
140 if ((state === "searching") ||142 (state !== "vcardImported")) {
141 (state === "vcardImported")) {143 mainPage.state = "default"
142 return
143 }144 }
144145
145 contactIndex = contact146 contactIndex = contact
146 mainPage.state = "default"
147 // this means a new contact was created147 // this means a new contact was created
148 if (mainPage.allowToQuit) {148 if (mainPage.allowToQuit) {
149 application.goBackToSourceApp()149 application.goBackToSourceApp()
@@ -157,42 +157,62 @@
157 contactList.reset()157 contactList.reset()
158 }158 }
159159
160 function showContactEditorPage(editorPage) {
161 contactList.currentIndex = -1;
162 mainPage.contactEditorPage = editorPage;
163 pageStack.addPageToNextColumn(mainPage, editorPage);
164 editorPage.ready();
165 editorPage.contactSaved.connect(onNewContactSaved);
166 }
167
168 function onNewContactSaved(contact) {160 function onNewContactSaved(contact) {
161 _creatingContact = true
162 moveListToContact(contact)
169 if (pageStack.columns > 1) {163 if (pageStack.columns > 1) {
170 showContact(contact);164 showContact(contact);
171 }165 }
172 }166 }
173167
168 function reloadContact()
169 {
170 fetchNewContactTimer.restart()
171 contactList.forceActiveFocus()
172 }
173
174 title: i18n.tr("Contacts")174 title: i18n.tr("Contacts")
175175
176 flickable: null176 flickable: null
177
178 Timer {
179 id: fetchNewContactTimer
180
181 interval: 0
182 repeat: false
183 onTriggered: {
184 if ((contactList.currentIndex >= 0) && (pageStack.columns > 1)) {
185 var currentContact = contactList.listModel.contacts[contactList.currentIndex]
186 if (mainPage.currentViewContactId === currentContact.contactId)
187 return
188
189 contactList.view._fetchContact(contactList.currentIndex, currentContact)
190 }
191 }
192 }
193
177 ContactsUI.ContactListView {194 ContactsUI.ContactListView {
178 id: contactList195 id: contactList
179 objectName: "contactListView"196 objectName: "contactListView"
197
198 focus: true
180 showImportOptions: !mainPage.pickMode &&199 showImportOptions: !mainPage.pickMode &&
181 mainPage.newPhoneToAdd === "" &&200 mainPage.newPhoneToAdd === "" &&
182 (!mainPage.contactEditorPage || !mainPage.contactEditorPage.active)201 pageStack.bottomEdge && (pageStack.bottomEdge.satus === BottomEdge.Hidden)
183 anchors {202 anchors {
184 top: parent.top203 top: parent.top
185 left: parent.left204 left: parent.left
186 bottom: keyboard.top205 bottom: keyboard.top
187 right: parent.right206 right: parent.right
188 }207 }
208 currentIndex: 0
189 filterTerm: searchField.text209 filterTerm: searchField.text
190 multiSelectionEnabled: true210 multiSelectionEnabled: true
191 multipleSelection: (mainPage.pickMode && mainPage.pickMultipleContacts) || !mainPage.pickMode211 multipleSelection: (mainPage.pickMode && mainPage.pickMultipleContacts) || !mainPage.pickMode
192 highlightSelected: pageStack.columns > 1212 highlightSelected: pageStack.columns > 1 && !mainPage._creatingContact
213 showNewContact: (pageStack.columns > 1) && pageStack.bottomEdge && (pageStack.bottomEdge.status === BottomEdge.Committed)
193 onAddContactClicked: mainPage.createContactWithPhoneNumber(label)214 onAddContactClicked: mainPage.createContactWithPhoneNumber(label)
194 onAddNewContactClicked: mainPage.createContactWithPhoneNumber(mainPage.newPhoneToAdd)215 onAddNewContactClicked: mainPage.createContactWithPhoneNumber(mainPage.newPhoneToAdd)
195
196 onContactClicked: mainPage.showContact(contact)216 onContactClicked: mainPage.showContact(contact)
197 onIsInSelectionModeChanged: mainPage.state = isInSelectionMode ? "selection" : "default"217 onIsInSelectionModeChanged: mainPage.state = isInSelectionMode ? "selection" : "default"
198 onSelectionCanceled: {218 onSelectionCanceled: {
@@ -208,25 +228,71 @@
208 }228 }
209229
210 onError: pageStack.contactModelError(error)230 onError: pageStack.contactModelError(error)
231 onActiveFocusChanged: {
232 if (activeFocus && (contactList.currentIndex === -1)) {
233 contactList.currentIndex = 0
234 }
235 }
236 onCountChanged: {
237 if (mainPage.active &&
238 (pageStack.columns > 1) &&
239 (contactList.currentIndex === -1)) {
240 contactList.currentIndex = 0
241 }
242 fetchNewContactTimer.restart()
243 }
244 onCurrentIndexChanged: {
245 if (!mainPage.contactIndex)
246 fetchNewContactTimer.restart()
247 }
248
249 //WORKAROUND: SDK does not allow us to disable focus for items due bug: #1514822
250 //because of that we need this
251 Keys.onRightPressed: {
252 // only move focus away when in edit mode
253 if (pageStack.bottomEdge.status === BottomEdge.Committed) {
254 var next = pageStack._nextItemInFocusChain(view, true)
255 if (next === searchField) {
256 pageStack._nextItemInFocusChain(next, true)
257 }
258 }
259 }
260 Keys.onTabPressed: {
261 var next = pageStack._nextItemInFocusChain(view, true)
262 if (next === searchField) {
263 pageStack._nextItemInFocusChain(next, true)
264 }
265 }
211 }266 }
212267
213 TextField {268 TextField {
214 id: searchField269 id: searchField
215270
271 //WORKAROUND: SDK does not allow us to disable focus for items due bug: #1514822
272 //because of that we need this
273 readonly property bool _allowFocus: true
274
216 anchors {275 anchors {
217 left: parent.left276 left: parent ? parent.left : undefined
218 right: parent.right277 right: parent ? parent.right : undefined
219 rightMargin: units.gu(2)278 rightMargin: units.gu(2)
220 }279 }
221 focus: false280
222 visible: false281 visible: false
223 onTextChanged: contactList.currentIndex = -1
224 inputMethodHints: Qt.ImhNoPredictiveText282 inputMethodHints: Qt.ImhNoPredictiveText
225 placeholderText: i18n.tr("Search...")283 placeholderText: i18n.tr("Search...")
226 onFocusChanged: {284 onVisibleChanged: {
227 if (visible && focus)285 if (visible) {
228 searchField.forceActiveFocus()286 if (activeFocus) {
287 Qt.inputMethod.show()
288 } else {
289 searchField.forceActiveFocus()
290 }
291 }
229 }292 }
293
294 Keys.onTabPressed: contactList.forceActiveFocus()
295 Keys.onDownPressed: contactList.forceActiveFocus()
230 }296 }
231297
232 Connections {298 Connections {
@@ -265,6 +331,8 @@
265 text: i18n.tr("Search")331 text: i18n.tr("Search")
266 iconName: "search"332 iconName: "search"
267 visible: !mainPage.isEmpty333 visible: !mainPage.isEmpty
334 enabled: mainPage.state === "default"
335 shortcut: "Ctrl+F"
268 onTriggered: {336 onTriggered: {
269 mainPage.state = (mainPage.state === "newphone" ? "newphoneSearching" : "searching")337 mainPage.state = (mainPage.state === "newphone" ? "newphoneSearching" : "searching")
270 contactList.showAllContacts()338 contactList.showAllContacts()
@@ -287,9 +355,21 @@
287 Action {355 Action {
288 text: i18n.tr("Settings")356 text: i18n.tr("Settings")
289 iconName: "settings"357 iconName: "settings"
290 onTriggered: pageStack.addPageToNextColumn(mainPage,358 onTriggered:{
291 Qt.resolvedUrl("./Settings/SettingsPage.qml"),359 var incubator = pageStack.addPageToNextColumn(mainPage,
292 {"contactListModel": contactList.listModel})360 Qt.resolvedUrl("./Settings/SettingsPage.qml"),
361 {"contactListModel": contactList.listModel})
362 incubator.onStatusChanged = function(status) {
363 if (status === Component.Ready) {
364 incubator.object.onActiveChanged.connect(function(active) {
365 console.debug("Active:" + incubator.object.active)
366 if (!incubator.object.active) {
367 mainPage.reloadContact()
368 }
369 })
370 }
371 }
372 }
293 }373 }
294 ]374 ]
295 PropertyChanges {375 PropertyChanges {
@@ -303,6 +383,10 @@
303 target: searchField383 target: searchField
304 text: ""384 text: ""
305 }385 }
386 PropertyChanges {
387 target: bottomEdgeLoader
388 enabled: true
389 }
306 },390 },
307 PageHeadState {391 PageHeadState {
308 id: searchingState392 id: searchingState
@@ -311,6 +395,8 @@
311 backAction: Action {395 backAction: Action {
312 iconName: "back"396 iconName: "back"
313 text: i18n.tr("Cancel")397 text: i18n.tr("Cancel")
398 enabled: mainPage.state === "searching" && !mainPage.bottomEdgeOpenOnNextCollumn
399 shortcut:"Esc"
314 onTriggered: {400 onTriggered: {
315 contactList.forceActiveFocus()401 contactList.forceActiveFocus()
316 mainPage.head.sections.selectedIndex = 0402 mainPage.head.sections.selectedIndex = 0
@@ -319,7 +405,7 @@
319 }405 }
320406
321 PropertyChanges {407 PropertyChanges {
322 target: bottomEdge408 target: bottomEdgeLoader
323 enabled: false409 enabled: false
324 }410 }
325411
@@ -347,7 +433,9 @@
347 backAction: Action {433 backAction: Action {
348 text: i18n.tr("Cancel selection")434 text: i18n.tr("Cancel selection")
349 iconName: "back"435 iconName: "back"
436 enabled: mainPage.state === "selection"
350 onTriggered: contactList.cancelSelection()437 onTriggered: contactList.cancelSelection()
438 shortcut: "Esc"
351 }439 }
352 actions: [440 actions: [
353 Action {441 Action {
@@ -405,7 +493,7 @@
405 actions: selectionState.actions493 actions: selectionState.actions
406 }494 }
407 PropertyChanges {495 PropertyChanges {
408 target: bottomEdge496 target: bottomEdgeLoader
409 enabled: false497 enabled: false
410 }498 }
411 },499 },
@@ -440,7 +528,7 @@
440 showAddNewButton: true528 showAddNewButton: true
441 }529 }
442 PropertyChanges {530 PropertyChanges {
443 target: bottomEdge531 target: bottomEdgeLoader
444 enabled: false532 enabled: false
445 }533 }
446 },534 },
@@ -462,7 +550,7 @@
462 backAction: vcardImportedState.backAction550 backAction: vcardImportedState.backAction
463 }551 }
464 PropertyChanges {552 PropertyChanges {
465 target: bottomEdge553 target: bottomEdgeLoader
466 enabled: false554 enabled: false
467 }555 }
468 PropertyChanges {556 PropertyChanges {
@@ -493,8 +581,11 @@
493 if (active && contactList.showAddNewButton) {581 if (active && contactList.showAddNewButton) {
494 contactList.positionViewAtBeginning()582 contactList.positionViewAtBeginning()
495 }583 }
584
496 if (active && (state === "searching")) {585 if (active && (state === "searching")) {
497 searchField.forceActiveFocus()586 searchField.forceActiveFocus()
587 } else if (active) {
588 contactList.forceActiveFocus()
498 }589 }
499 }590 }
500591
@@ -517,8 +608,8 @@
517 !contactList.favouritesIsSelected &&608 !contactList.favouritesIsSelected &&
518 mainPage.isEmpty &&609 mainPage.isEmpty &&
519 (mainPage.newPhoneToAdd === "") &&610 (mainPage.newPhoneToAdd === "") &&
520 !(contactList.filterTerm && contactList.filterTerm !== "")) &&611 !(contactList.filterTerm && contactList.filterTerm !== ""))
521 bottomEdge.visible612 //&& bottomEdge.visible
522613
523 Behavior on visible {614 Behavior on visible {
524 SequentialAnimation {615 SequentialAnimation {
@@ -643,111 +734,34 @@
643 }734 }
644 }735 }
645736
646 Component {737 Loader {
647 id: editorPageBottomEdge738 id: bottomEdgeLoader
648 ABContactEditorPage {739
649 backIconName: "down"740 enabled: false
650 implicitWidth: mainPage.width741 active: (pageStack.columns === 1) && bottomEdgeLoader.enabled
651 implicitHeight: mainPage.height742 sourceComponent: ABNewContactBottomEdge {
652 model: contactList.listModel743 pageStack: mainPage.pageStack
653 contact: ContactsJS.createEmptyContact("", mainPage)744 parent: mainPage
654 initialFocusSection: "name"745 hint.flickable: contactList.view
655 enabled: false746 }
656 }747 }
657 }748
658749 Binding {
659 Component {750 target: pageStack
660 id: emptyContact751 property: 'bottomEdge'
661 ContactsUI.ContactDelegate {752 value: bottomEdgeLoader.item
662 property Contact contact: Contact {753 when: bottomEdgeLoader.status == Loader.Ready
663 Name {
664 firstName: i18n.tr("New contact")
665 }
666 Avatar {
667 imageUrl: "image://theme/contact"
668 }
669 }
670 width: mainPage.width
671 }
672 }
673
674 BottomEdge {
675 id: bottomEdge
676 objectName: "bottomEdge"
677
678 property var incubator
679
680 // FIXME: this is a workaround for the lack of fully asynchronous loading
681 // of Pages in AdaptativePageLayout
682 function createObjectAsynchronously(url, properties, callback) {
683 var component = Qt.createComponent(url, Component.Asynchronous);
684 if (component.status == Component.Ready) {
685 incubateObject(component, properties, callback);
686 } else {
687 component.onStatusChanged.connect(function(status) {
688 if (status == Component.Ready) {
689 incubateObject(component, properties, callback);
690 }
691 });
692 }
693 }
694
695 function incubateObject(component, properties, callback) {
696 if (component.status == Component.Ready) {
697 incubator = component.incubateObject(null,
698 properties,
699 Qt.Asynchronous);
700 incubator.onStatusChanged = function(status) {
701 if (status == Component.Ready) {
702 callback(incubator.object);
703 incubator = null;
704 }
705 }
706 }
707 }
708
709 function loadEditorPage() {
710 var newContact = ContactsJS.createEmptyContact("", mainPage);
711 createObjectAsynchronously(Qt.resolvedUrl("ABContactEditorPage.qml"),
712 {model: contactList.listModel,
713 contact: newContact,
714 initialFocusSection: "name"},
715 showContactEditorPage);
716 }
717
718 anchors.fill: parent
719 contentComponent: pageStack.columns == 1 ? editorPageBottomEdge : emptyContact
720 flickable: contactList
721 iconName: "contact-new"
722 enabled: !contactList.isInSelectionMode
723 backGroundEffectEnabled: pageStack.columns === 1
724
725 onOpenBegin: {
726 contactList.prepareNewContact = true;
727 contactList.positionViewAtBeginning();
728 if (pageStack.columns > 1) {
729 loadEditorPage();
730 }
731 }
732 onOpenEnd: {
733 bottomEdge.visible = false;
734 contactList.showNewContact = true;
735 if (pageStack.columns <= 1) {
736 showContactEditorPage(bottomEdge.content);
737 }
738 }
739
740 onClicked: {
741 bottomEdge.open();
742 }
743 }754 }
744755
745 Connections {756 Connections {
746 target: mainPage.contactModel757 target: mainPage.contactModel
758
747 onContactsChanged: {759 onContactsChanged: {
748 if (contactIndex) {760 if (contactIndex) {
749 contactList.positionViewAtContact(mainPage.contactIndex)761 contactList.positionViewAtContact(mainPage.contactIndex)
750 mainPage.contactIndex = null762 mainPage.contactIndex = null
763 // at this point the operation has finished already
764 mainPage._creatingContact = false
751 }765 }
752 }766 }
753 onImportCompleted: {767 onImportCompleted: {
@@ -775,23 +789,4 @@
775 }789 }
776 }790 }
777 }791 }
778
779 Connections {
780 target: mainPage.contactViewPage
781 onEditContact: {
782 openEditPage(editPageProperties, mainPage.contactViewPage);
783 }
784 }
785
786 Connections {
787 target: mainPage.contactEditorPage
788 onActiveChanged: {
789 if (!mainPage.contactEditorPage.active) {
790 contactList.prepareNewContact = false;
791 contactList.showNewContact = false;
792 bottomEdge.visible = true;
793 bottomEdge.close();
794 }
795 }
796 }
797}792}
798793
=== modified file 'src/imports/ABContactViewPage.qml'
--- src/imports/ABContactViewPage.qml 2015-10-28 01:08:39 +0000
+++ src/imports/ABContactViewPage.qml 2015-12-04 15:09:43 +0000
@@ -1,4 +1,4 @@
1/*1/*
2 * Copyright (C) 2012-2015 Canonical, Ltd.2 * Copyright (C) 2012-2015 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,7 @@
28 objectName: "contactViewPage"28 objectName: "contactViewPage"
2929
30 property string addPhoneToContact: ""30 property string addPhoneToContact: ""
31 property var editorPage: null
31 signal editContact(var editPageProperties)32 signal editContact(var editPageProperties)
3233
33 head.actions: [34 head.actions: [
@@ -50,9 +51,14 @@
5051
51 text: i18n.tr("Edit")52 text: i18n.tr("Edit")
52 iconName: "edit"53 iconName: "edit"
54 enabled: root.active
55 shortcut: "Ctrl+e"
53 onTriggered: {56 onTriggered: {
54 editContact({model: root.model,57 pageStack.addPageToCurrentColumn(root,
55 contact: root.contact});58 Qt.resolvedUrl("ABContactEditorPage.qml"),
59 { model: root.model,
60 contact: root.contact,
61 backIconName: 'back'})
56 }62 }
57 }63 }
58 ]64 ]
@@ -100,4 +106,26 @@
100 id: contactShareComponent106 id: contactShareComponent
101 ContactSharePage {}107 ContactSharePage {}
102 }108 }
109
110 Loader {
111 id: bottomEdgeLoader
112
113 active: root.pageStack && root.pageStack.columns > 1
114 sourceComponent: ABNewContactBottomEdge {
115 id: bottomEdge
116
117 parent: root
118 pageStack: root.pageStack
119 hint.flickable: root.flickable
120 }
121
122 Binding {
123 target: pageStack
124 property: 'bottomEdge'
125 value: bottomEdgeLoader.item
126 when: bottomEdgeLoader.status == Loader.Ready
127 }
128 }
129
130 Component.onDestruction: console.debug("VIEW DESTROYED")
103}131}
104132
=== added file 'src/imports/ABNewContactBottomEdge.qml'
--- src/imports/ABNewContactBottomEdge.qml 1970-01-01 00:00:00 +0000
+++ src/imports/ABNewContactBottomEdge.qml 2015-12-04 15:09:43 +0000
@@ -0,0 +1,67 @@
1/*
2 * Copyright (C) 2012-2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.4
18import Ubuntu.Components 1.3
19import Ubuntu.Contacts 0.1 as ContactsUI
20
21BottomEdge {
22 id: bottomEdge
23 objectName: "bottomEdge"
24
25 property var pageStack: null
26 property var _contactToEdit: null
27 property var _modelToEdit: null
28
29 function editContact(contact, model)
30 {
31 _contactToEdit = contact
32 _modelToEdit = model
33 commit()
34 }
35
36 hint {
37 action: Action {
38 iconName: "contact-new"
39 onTriggered: bottomEdge.commit()
40 shortcut: "ctrl+n"
41 enabled: bottomEdge.enabled
42 }
43 }
44 contentComponent: editorPageBottomEdge
45 onCommitCompleted: {
46 var editorPage = bottomEdge.contentItem
47 bottomEdge.pageStack.addPageToCurrentColumn(bottomEdge.parent, bottomEdge.contentItem)
48 editorPage.contact = bottomEdge._contactToEdit
49 editorPage.model = bottomEdge._modelToEdit
50 bottomEdge._contactToEdit = null
51 bottomEdge._modelToEdit = null
52 }
53
54 Component {
55 id: editorPageBottomEdge
56
57 ABContactEditorPage {
58 implicitWidth: mainPage.width
59 implicitHeight: bottomEdge.height
60 contact: ContactsUI.ContactsJS.createEmptyContact("", bottomEdge)
61 initialFocusSection: "name"
62 enabled: false
63 visible: bottomEdge.satus != BottomEdge.Hidden
64 onCanceled: bottomEdge.collapse()
65 }
66 }
67}
068
=== removed file 'src/imports/BottomEdge.qml'
--- src/imports/BottomEdge.qml 2015-11-19 01:02:12 +0000
+++ src/imports/BottomEdge.qml 1970-01-01 00:00:00 +0000
@@ -1,321 +0,0 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.4
18import Ubuntu.Components 1.3
19
20Item {
21 id: bottomEdge
22
23 readonly property alias content: bottomEdgeLoader.item
24 readonly property bool fullLoaded: bottomEdgeLoader.status == Loader.Ready
25
26 property bool opened: false
27 property Component contentComponent
28 property string iconName
29 property Item flickable
30 property alias backGroundEffectEnabled: darkBg.visible
31
32 signal openBegin
33 signal openEnd
34 signal clicked
35 visible: enabled
36
37 function open() {
38 bottomEdge.state = "expanded";
39 }
40
41 function close() {
42 bottomEdge.state = "collapsed";
43 }
44
45 Rectangle {
46 id: darkBg
47
48 anchors.fill: parent
49 color: "black"
50 opacity: 0.0
51 }
52
53 Item {
54 id: bottomEdgeBody
55 anchors {
56 left: parent.left
57 right: parent.right
58 }
59 height: bottomEdgeContent.height
60
61 Item {
62 id: bottomEdgeContent
63 anchors {
64 left: parent.left
65 right: parent.right
66 }
67 height: bottomEdgeLoader.height
68
69 Item {
70 id: bottomEdgeShadows
71 anchors.fill: bottomEdgeContent
72
73 BottomEdgeShadow {
74 anchors.bottom: parent.top
75 }
76
77 BottomEdgeShadow {
78 anchors.top: parent.bottom
79 rotation: 180
80 }
81 }
82
83 Rectangle {
84 anchors.fill: parent
85 color: Theme.palette.normal.background
86 }
87
88 Loader {
89 id: bottomEdgeLoader
90 sourceComponent: bottomEdge.contentComponent
91 asynchronous: true
92 active: bottomEdge.enabled
93 }
94 }
95
96 BottomEdgeHint {
97 id: bottomEdgeHint
98
99 anchors.bottom: bottomEdgeBody.top
100 iconName: bottomEdge.iconName
101 onClicked: bottomEdge.clicked()
102
103 Connections {
104 target: bottomEdgeDragArea
105 onClosedChanged: {
106 if (!bottomEdgeDragArea.closed) {
107 bottomEdgeHint.state = "Visible";
108 }
109 }
110 }
111
112 Connections {
113 target: flickable
114 onVerticalVelocityChanged: {
115 if (!bottomEdgeDragArea.closed) {
116 return;
117 }
118
119 if (flickable.verticalVelocity > 0) {
120 bottomEdgeHint.state = "Hidden";
121 } else if (flickable.verticalVelocity < 0) {
122 bottomEdgeHint.state = "Visible";
123 }
124 }
125 }
126 }
127 }
128
129
130 state: "collapsed"
131 states: [
132 State {
133 name: "collapsed"
134 ParentChange {
135 target: bottomEdgeContent
136 parent: bottomEdgeBody
137 x: 0
138 y: 0
139 }
140 PropertyChanges {
141 target: bottomEdgeBody
142 y: bottomEdgeDragArea.drag.maximumY
143 }
144 PropertyChanges {
145 target: bottomEdgeContent
146 opacity: 0.0
147 }
148 PropertyChanges {
149 target: darkBg
150 opacity: 0.0
151 }
152 },
153 State {
154 name: "expanded"
155 ParentChange {
156 target: bottomEdgeContent
157 parent: bottomEdge
158 x: 0
159 y: 0
160 }
161 PropertyChanges {
162 target: bottomEdgeContent
163 opacity: 1.0
164 }
165 PropertyChanges {
166 target: bottomEdgeBody
167 y: 0
168 }
169 PropertyChanges {
170 target: bottomEdgeShadows
171 opacity: 0.0
172 visible: true
173 }
174 PropertyChanges {
175 target: darkBg
176 opacity: 0.8
177 }
178 },
179 State {
180 name: "floating"
181 when: bottomEdgeDragArea.drag.active
182 PropertyChanges {
183 target: bottomEdgeContent
184 opacity: 1.0
185 }
186 PropertyChanges {
187 target: darkBg
188 opacity: bottomEdgeBody.y > 0 ? 0.8 - (bottomEdgeBody.y / bottomEdgeDragArea.drag.maximumY) : 0.8
189 }
190 }
191 ]
192
193 transitions: [
194 Transition {
195 to: "collapsed"
196 SequentialAnimation {
197 alwaysRunToEnd: true
198 ParallelAnimation {
199 ParentAnimation {
200 UbuntuNumberAnimation {
201 properties: "x,y"
202 duration: UbuntuAnimation.SlowDuration
203 target: bottomEdgeContent
204 }
205 }
206 UbuntuNumberAnimation {
207 target: bottomEdgeBody
208 property: "y"
209 duration: UbuntuAnimation.SlowDuration
210 }
211 UbuntuNumberAnimation {
212 target: darkBg
213 property: "opacity"
214 duration: UbuntuAnimation.SlowDuration
215 }
216 }
217 PropertyAction {
218 target: bottomEdgeContent
219 property: "opacity"
220 }
221 ScriptAction {
222 script: {
223 bottomEdgeLoader.active = false
224 bottomEdgeLoader.active = true
225 bottomEdge.opened = false
226 }
227 }
228 }
229 },
230 Transition {
231 to: "expanded"
232 SequentialAnimation {
233 alwaysRunToEnd: true
234 ParallelAnimation {
235 ScriptAction {
236 script: bottomEdge.openBegin()
237 }
238 ParentAnimation {
239 UbuntuNumberAnimation {
240 properties: "x,y"
241 duration: UbuntuAnimation.SlowDuration
242 target: bottomEdgeContent
243 }
244 }
245 UbuntuNumberAnimation {
246 target: bottomEdgeShadows
247 property: "opacity"
248 duration: UbuntuAnimation.SlowDuration
249 }
250 UbuntuNumberAnimation {
251 target: darkBg
252 property: "opacity"
253 duration: UbuntuAnimation.SlowDuration
254 }
255 }
256 UbuntuNumberAnimation {
257 target: bottomEdgeContent
258 property: "opacity"
259 duration: UbuntuAnimation.FastDuration
260 }
261 ScriptAction {
262 script: {
263 bottomEdge.opened = true
264 bottomEdge.openEnd()
265 }
266
267 }
268 }
269 }
270 ]
271
272 MouseArea {
273 id: bottomEdgeDragArea
274 objectName: "bottomEdgeDragArea"
275
276 property real previousY: -1
277 property string dragDirection: "None"
278 property bool closed: drag.target.y == bottomEdgeDragArea.drag.maximumY
279 && !bottomEdgeDragArea.pressed
280
281 preventStealing: true
282 propagateComposedEvents: true
283 drag {
284 axis: Drag.YAxis
285 target: bottomEdgeBody
286 minimumY: 0
287 maximumY: bottomEdge.height
288 }
289
290 anchors {
291 left: parent.left
292 right: parent.right
293 bottom: parent.bottom
294 }
295 height: bottomEdgeHint.height
296
297 onPressed: {
298 previousY = mouse.y;
299 }
300
301 onReleased: {
302 if (dragDirection === "BottomToTop") {
303 bottomEdge.state = "expanded";
304 } else {
305 bottomEdge.state = "collapsed";
306 }
307 previousY = -1;
308 dragDirection = "None";
309 }
310
311 onMouseYChanged: {
312 var yOffset = previousY - mouseY;
313 // skip if was a small move
314 if (Math.abs(yOffset) <= units.gu(2)) {
315 return;
316 }
317 previousY = mouseY;
318 dragDirection = yOffset > 0 ? "BottomToTop" : "TopToBottom";
319 }
320 }
321}
3220
=== removed file 'src/imports/BottomEdgeShadow.qml'
--- src/imports/BottomEdgeShadow.qml 2015-09-10 14:47:38 +0000
+++ src/imports/BottomEdgeShadow.qml 1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.4
18import Ubuntu.Components 1.3
19
20Rectangle {
21 id: bottomEdgeShadow
22 anchors {
23 left: parent.left
24 right: parent.right
25 }
26 height: units.gu(1)
27 gradient: Gradient {
28 GradientStop { position: 0.0; color: Qt.rgba(0.0, 0.0, 0.0, 0.0) }
29 GradientStop { position: 1.0; color: Qt.rgba(0.0, 0.0, 0.0, 0.3) }
30 }
31}
320
=== modified file 'src/imports/CMakeLists.txt'
--- src/imports/CMakeLists.txt 2015-11-19 14:41:18 +0000
+++ src/imports/CMakeLists.txt 2015-12-04 15:09:43 +0000
@@ -4,10 +4,9 @@
4 ABContactListPage.qml4 ABContactListPage.qml
5 ABContactEditorPage.qml5 ABContactEditorPage.qml
6 ABContactViewPage.qml6 ABContactViewPage.qml
7 ABNewContactBottomEdge.qml
7 ContentHubProxy.qml8 ContentHubProxy.qml
8 MainWindow.qml9 MainWindow.qml
9 BottomEdgeShadow.qml
10 BottomEdge.qml
11)10)
1211
13install(FILES ${ADDRESS_BOOK_APP_QMLS}12install(FILES ${ADDRESS_BOOK_APP_QMLS}
1413
=== modified file 'src/imports/MainWindow.qml'
--- src/imports/MainWindow.qml 2015-10-26 13:18:11 +0000
+++ src/imports/MainWindow.qml 2015-12-04 15:09:43 +0000
@@ -101,18 +101,41 @@
101 width: units.gu(90)101 width: units.gu(90)
102 height: units.gu(71)102 height: units.gu(71)
103 anchorToKeyboard: false103 anchorToKeyboard: false
104 focus: false
104105
105 AdaptivePageLayout {106 AdaptivePageLayout {
106 id: mainStack107 id: mainStack
107108
108 primaryPage: contactPage
109 property var contactListPage: null109 property var contactListPage: null
110 property var bottomEdge: null
110111
111 function resetStack()112 function resetStack()
112 {113 {
113 mainStack.removePages(primaryPage);114 mainStack.removePages(primaryPage);
114 }115 }
115116
117 function _nextItemInFocusChain(item, foward)
118 {
119 var next = item.nextItemInFocusChain(foward)
120 var first = next
121 //WORKAROUND: SDK does not allow us to disable focus for items due bug: #1514822
122 //because of that we need this
123 while (!next || !next.hasOwnProperty("_allowFocus")) {
124 next = next.nextItemInFocusChain(foward)
125
126 // avoid loop
127 if (next === first) {
128 next = null
129 break
130 }
131 }
132 if (next) {
133 next.forceActiveFocus()
134 }
135 return next
136 }
137
138 primaryPage: contactPage
116 onContactListPageChanged: {139 onContactListPageChanged: {
117 if (contentHubLoader.status === Loader.Ready) {140 if (contentHubLoader.status === Loader.Ready) {
118 contentHubLoader.item.pageStack = mainStack141 contentHubLoader.item.pageStack = mainStack
@@ -141,6 +164,7 @@
141 }164 }
142 }165 }
143 ]166 ]
167
144 }168 }
145169
146 ABContactListPage {170 ABContactListPage {
@@ -196,6 +220,10 @@
196220
197 // If application was called from uri handler and lost the focus reset the app to normal state221 // If application was called from uri handler and lost the focus reset the app to normal state
198 onAppActiveChanged: {222 onAppActiveChanged: {
223 if (appActive) {
224 mainStack.forceActiveFocus()
225 }
226
199 if (!appActive && mainStack.contactListPage) {227 if (!appActive && mainStack.contactListPage) {
200 mainStack.contactListPage.returnToNormalState()228 mainStack.contactListPage.returnToNormalState()
201 }229 }
202230
=== modified file 'src/imports/Settings/SettingsPage.qml'
--- src/imports/Settings/SettingsPage.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Settings/SettingsPage.qml 2015-12-04 15:09:43 +0000
@@ -1,4 +1,4 @@
1/*1/*
2 * Copyright (C) 2015 Canonical, Ltd.2 * Copyright (C) 2015 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
@@ -64,15 +64,56 @@
64 onCountChanged: numberFlickable.contentY = 064 onCountChanged: numberFlickable.contentY = 0
65 }65 }
66 ListItem.Standard {66 ListItem.Standard {
67 id: addGoogleAccountItem
68
69 function activate()
70 {
71 onlineAccountsHelper.setupExec()
72 }
73
67 text: i18n.tr("Add Google account")74 text: i18n.tr("Add Google account")
68 progression: true75 progression: true
69 onClicked: onlineAccountsHelper.setupExec()76
77 onClicked: addGoogleAccountItem.activate()
78 Keys.onRightPressed: addGoogleAccountItem.activate()
79 Keys.onDownPressed: {
80 if (importFromSimItem.enabled) {
81 importFromSimItem.forceActiveFocus()
82 }
83 }
84
85 // selection visual feedback
86 __foregroundColor: (activeFocus && (pageStack.columns > 1)) ? "white" : Theme.palette.normal.foreground
87 Rectangle {
88 color: UbuntuColors.orange
89 anchors.fill: parent
90 visible:addGoogleAccountItem.activeFocus
91 z: -1
92 }
70 }93 }
71 ListItem.Standard {94 ListItem.Standard {
95 id: importFromSimItem
96
97 function activate()
98 {
99 pageStack.addPageToCurrentColumn(root, simCardImportPageComponent)
100 }
101
72 text: i18n.tr("Import from SIM")102 text: i18n.tr("Import from SIM")
73 progression: true103 progression: true
74 onClicked: pageStack.addPageToCurrentColumn(root, simCardImportPageComponent)
75 enabled: (simList.sims.length > 0) && (simList.present.length > 0)104 enabled: (simList.sims.length > 0) && (simList.present.length > 0)
105 onClicked: importFromSimItem.activate()
106 Keys.onRightPressed: importFromSimItem.activate()
107 Keys.onUpPressed: addGoogleAccountItem.forceActiveFocus()
108
109 // selection visual feedback
110 __foregroundColor: (activeFocus && (pageStack.columns > 1)) ? "white" : Theme.palette.normal.foreground
111 Rectangle {
112 color: UbuntuColors.orange
113 anchors.fill: parent
114 visible: importFromSimItem.activeFocus
115 z: -1
116 }
76 }117 }
77 }118 }
78 }119 }
@@ -89,4 +130,14 @@
89 sims: simList.sims130 sims: simList.sims
90 }131 }
91 }132 }
133
134 Keys.onDownPressed: addGoogleAccountItem.forceActiveFocus()
135 Keys.onRightPressed: addGoogleAccountItem.forceActiveFocus()
136 Keys.onLeftPressed: pageStack.removePages(root)
137 Keys.onEscapePressed: pageStack.removePages(root)
138 onActiveChanged: {
139 if (active) {
140 root.forceActiveFocus()
141 }
142 }
92}143}
93144
=== modified file 'src/imports/Ubuntu/AddressBook/Base/ContactDetailBase.qml'
--- src/imports/Ubuntu/AddressBook/Base/ContactDetailBase.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/Base/ContactDetailBase.qml 2015-12-04 15:09:43 +0000
@@ -18,15 +18,19 @@
18import QtContacts 5.0 as QtContacts18import QtContacts 5.0 as QtContacts
19import Ubuntu.Components.ListItems 1.3 as ListItem19import Ubuntu.Components.ListItems 1.3 as ListItem
2020
21ListItem.Empty {21FocusScope {
22 id: root22 id: root
23 objectName: detail ? "base_" + detailToString(detail.type, -1) + "_" + index : ""23 objectName: detail ? "base_" + detailToString(detail.type, -1) + "_" + index : ""
2424
25 property variant action: null
25 property QtObject contact: null26 property QtObject contact: null
26 property QtObject detail: null27 property QtObject detail: null
27 property variant fields: null28 property variant fields: null
28 // help to test used to retrieve the correct element29 // help to test used to retrieve the correct element
29 property int index: -130 property int index: -1
31 property alias highlightOnFocus: highlight.visible
32
33 signal clicked()
3034
31 function detailToString(detail, field)35 function detailToString(detail, field)
32 {36 {
@@ -98,13 +102,24 @@
98 }102 }
99 }103 }
100104
101 highlightWhenPressed: false
102 showDivider: false
103
104 Rectangle {105 Rectangle {
106 id: highlight
107
105 anchors.fill: parent108 anchors.fill: parent
106 opacity: 0.1109 opacity: 0.1
107 visible: root.selected110 visible: root.activeFocus
111 color: "black"
108 z: 100112 z: 100
109 }113 }
114
115 MouseArea {
116 anchors.fill: parent
117
118 onClicked: {
119 if (action) {
120 action.triggered(action)
121 }
122 root.clicked()
123 }
124 }
110}125}
111126
=== modified file 'src/imports/Ubuntu/AddressBook/Base/ContactDetailGroupBase.qml'
--- src/imports/Ubuntu/AddressBook/Base/ContactDetailGroupBase.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/Base/ContactDetailGroupBase.qml 2015-12-04 15:09:43 +0000
@@ -33,6 +33,7 @@
33 property int minimumHeight: 033 property int minimumHeight: 0
34 property bool loaded: false34 property bool loaded: false
35 property bool showEmpty: true35 property bool showEmpty: true
36 property bool forceFocusOnFieldCreation: false
3637
37 signal newFieldAdded(var index)38 signal newFieldAdded(var index)
3839
@@ -146,7 +147,7 @@
146 newFields.push(detailItem.item)147 newFields.push(detailItem.item)
147 root.newFieldAdded(detailItem.item)148 root.newFieldAdded(detailItem.item)
148 root.inputFields = newFields149 root.inputFields = newFields
149 if (root.loaded) {150 if (root.loaded && root.forceFocusOnFieldCreation) {
150 item.forceActiveFocus()151 item.forceActiveFocus()
151 }152 }
152 }153 }
153154
=== modified file 'src/imports/Ubuntu/AddressBook/Base/RemoveContactsDialog.qml'
--- src/imports/Ubuntu/AddressBook/Base/RemoveContactsDialog.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/Base/RemoveContactsDialog.qml 2015-12-04 15:09:43 +0000
@@ -53,6 +53,7 @@
53 }53 }
5454
55 Button {55 Button {
56 id: acceptButton
56 objectName: "removeContactsDialog.Yes"57 objectName: "removeContactsDialog.Yes"
57 anchors {58 anchors {
58 left: parent.left59 left: parent.left
@@ -61,10 +62,16 @@
61 }62 }
62 text: i18n.dtr("address-book-app", "Yes")63 text: i18n.dtr("address-book-app", "Yes")
63 color: UbuntuColors.green64 color: UbuntuColors.green
64 onClicked: accepted()65 action: Action {
66 shortcut: "return"
67 onTriggered: {
68 accepted()
69 }
70 }
65 }71 }
6672
67 Button {73 Button {
74 id: cancelButton
68 objectName: "removeContactsDialog.No"75 objectName: "removeContactsDialog.No"
69 anchors {76 anchors {
70 left: parent.left77 left: parent.left
@@ -73,6 +80,16 @@
73 }80 }
74 text: i18n.dtr("address-book-app", "No")81 text: i18n.dtr("address-book-app", "No")
75 color: UbuntuColors.red82 color: UbuntuColors.red
76 onClicked: canceled()83 action: Action {
84 shortcut: "esc"
85 onTriggered: {
86 canceled()
87 }
88 }
89 }
90
91 Component.onDestruction: {
92 cancelButton.action.shortcut = ""
93 acceptButton.action.shortcut = ""
77 }94 }
78}95}
7996
=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml'
--- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml 2015-10-29 18:11:08 +0000
+++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailAvatarEditor.qml 2015-12-04 15:09:43 +0000
@@ -68,6 +68,7 @@
68 detail: contact ? contact.detail(ContactDetail.Avatar) : null68 detail: contact ? contact.detail(ContactDetail.Avatar) : null
69 implicitHeight: units.gu(8)69 implicitHeight: units.gu(8)
70 implicitWidth: units.gu(8)70 implicitWidth: units.gu(8)
71 highlightOnFocus: false
7172
72 UbuntuShape {73 UbuntuShape {
73 id: avatar74 id: avatar
7475
=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailGroupWithTypeEditor.qml'
--- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailGroupWithTypeEditor.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailGroupWithTypeEditor.qml 2015-12-04 15:09:43 +0000
@@ -98,29 +98,19 @@
98 return changed98 return changed
99 }99 }
100100
101 headerDelegate: Empty {101 forceFocusOnFieldCreation: true
102 headerDelegate: Label {
102 id: header103 id: header
103 highlightWhenPressed: false104
104105 width: root.width - units.gu(4)
105 width: root.width106 x: units.gu(2)
106 height: units.gu(5)107 height: units.gu(4)
107 // disable listview mouse area108 text: root.title
108 __mouseArea.visible: false109 // style
109 divider.anchors.leftMargin: units.gu(2)110 fontSize: "medium"
110 divider.anchors.rightMargin: units.gu(2)111 verticalAlignment: Text.AlignVCenter
111112 ThinDivider {
112 Label {113 anchors.bottom: parent.bottom
113 anchors {
114 verticalCenter: parent.verticalCenter
115 left: parent.left
116 right: parent.right
117 margins: units.gu(2)
118 }
119
120 text: root.title
121
122 // style
123 fontSize: "medium"
124 }114 }
125 }115 }
126116
@@ -157,7 +147,6 @@
157 fields: root.fields147 fields: root.fields
158 height: implicitHeight148 height: implicitHeight
159 width: root.width149 width: root.width
160 selected: activeFocus
161150
162 inputMethodHints: root.inputMethodHints151 inputMethodHints: root.inputMethodHints
163 onDetailChanged: updateCombo(false)152 onDetailChanged: updateCombo(false)
164153
=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml'
--- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml 2015-12-04 15:09:43 +0000
@@ -55,6 +55,7 @@
55 spacing: units.gu(1)55 spacing: units.gu(1)
56 detail: root.contact ? root.contact.name : null56 detail: root.contact ? root.contact.name : null
57 fields: [ Name.FirstName, Name.LastName ]57 fields: [ Name.FirstName, Name.LastName ]
58 highlightOnFocus: false
5859
59 fieldDelegate: TextInputDetail {60 fieldDelegate: TextInputDetail {
60 id: textInputDetail61 id: textInputDetail
6162
=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml'
--- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml 2015-12-04 15:09:43 +0000
@@ -87,7 +87,8 @@
87 property real myHeight: sources.currentlyExpanded ? sources.containerHeight + units.gu(6) + label.height : sources.itemHeight + units.gu(6) + label.height87 property real myHeight: sources.currentlyExpanded ? sources.containerHeight + units.gu(6) + label.height : sources.itemHeight + units.gu(6) + label.height
8888
89 detail: root.contact ? contact.detail(ContactDetail.SyncTarget) : null89 detail: root.contact ? contact.detail(ContactDetail.SyncTarget) : null
90 implicitHeight: root.isNewContact && sources.model && (sources.model.count > 1) ? myHeight : 090 height: root.isNewContact && sources.model && (sources.model.count > 1) ? myHeight : 0
91 visible: height > 0
9192
92 ContactModel {93 ContactModel {
93 id: sourceModel94 id: sourceModel
@@ -144,8 +145,12 @@
144 ThinDivider {145 ThinDivider {
145 id: divider146 id: divider
146147
147 anchors.top: label.bottom148 anchors {
148 }149 top: label.bottom
150 leftMargin: units.gu(2)
151 rightMargin: units.gu(2)
152 }
153 }
149154
150 OptionSelector {155 OptionSelector {
151 id: sources156 id: sources
152157
=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailWithTypeEditor.qml'
--- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailWithTypeEditor.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailWithTypeEditor.qml 2015-12-04 15:09:43 +0000
@@ -70,7 +70,6 @@
70 }70 }
7171
72 // disable listview mouse area72 // disable listview mouse area
73 __mouseArea.visible: false
74 enabled: root.detail ? !root.detail.readOnly : false73 enabled: root.detail ? !root.detail.readOnly : false
75 implicitHeight: detailTypeSelector.height + fieldValues.height + units.gu(2)74 implicitHeight: detailTypeSelector.height + fieldValues.height + units.gu(2)
76 opacity: enabled ? 1.0 : 0.575 opacity: enabled ? 1.0 : 0.5
7776
=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml'
--- src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml 2015-12-04 15:09:43 +0000
@@ -31,7 +31,6 @@
31 property QtObject model: null31 property QtObject model: null
32 property QtObject activeItem: null32 property QtObject activeItem: null
3333
34
35 property string initialFocusSection: ""34 property string initialFocusSection: ""
36 property var newDetails: []35 property var newDetails: []
3736
@@ -39,9 +38,7 @@
39 readonly property bool isContactValid: !avatarEditor.busy && (!nameEditor.isEmpty() || !phonesEditor.isEmpty())38 readonly property bool isContactValid: !avatarEditor.busy && (!nameEditor.isEmpty() || !phonesEditor.isEmpty())
4039
41 signal contactSaved(var contact);40 signal contactSaved(var contact);
4241 signal canceled()
43 // priv
44 property bool _edgeReady: false
4542
46 function cancel() {43 function cancel() {
47 for (var i = 0; i < contactEditor.newDetails.length; ++i) {44 for (var i = 0; i < contactEditor.newDetails.length; ++i) {
@@ -60,6 +57,7 @@
60 } else {57 } else {
61 pageStack.pop()58 pageStack.pop()
62 }59 }
60 contactEditor.canceled()
63 }61 }
6462
65 function save() {63 function save() {
@@ -105,7 +103,7 @@
105 }103 }
106104
107 function makeMeVisible(item) {105 function makeMeVisible(item) {
108 if (!_edgeReady || !item) {106 if (!enabled || !item) {
109 return107 return
110 }108 }
111109
@@ -133,8 +131,6 @@
133 function ready()131 function ready()
134 {132 {
135 enabled = true133 enabled = true
136 _edgeReady = true
137
138 switch (contactEditor.initialFocusSection)134 switch (contactEditor.initialFocusSection)
139 {135 {
140 case "phones":136 case "phones":
@@ -153,6 +149,7 @@
153 }149 }
154150
155 title: isNewContact ? i18n.dtr("address-book-app", "New contact") : i18n.dtr("address-book-app", "Edit")151 title: isNewContact ? i18n.dtr("address-book-app", "New contact") : i18n.dtr("address-book-app", "Edit")
152 enabled: false
156153
157 Timer {154 Timer {
158 id: focusTimer155 id: focusTimer
@@ -181,7 +178,9 @@
181 contentWidth: parent.width178 contentWidth: parent.width
182179
183 //after add a new field we need to wait for the contentHeight to change to scroll to the correct position180 //after add a new field we need to wait for the contentHeight to change to scroll to the correct position
184 onContentHeightChanged: contactEditor.makeMeVisible(contactEditor.activeItem)181 onContentHeightChanged: {
182 contactEditor.makeMeVisible(contactEditor.activeItem)
183 }
185184
186 Column {185 Column {
187 id: contents186 id: contents
@@ -195,6 +194,7 @@
195 height: childrenRect.height194 height: childrenRect.height
196195
197 Row {196 Row {
197 id: editEditor
198 function save()198 function save()
199 {199 {
200 var avatarSave = avatarEditor.save()200 var avatarSave = avatarEditor.save()
@@ -213,7 +213,7 @@
213 leftMargin: units.gu(2)213 leftMargin: units.gu(2)
214 right: parent.right214 right: parent.right
215 }215 }
216 height: Math.max(avatarEditor.height, nameEditor.height) - units.gu(4)216 height: Math.max(avatarEditor.height, nameEditor.height) - units.gu(2)
217217
218 ContactDetailAvatarEditor {218 ContactDetailAvatarEditor {
219 id: avatarEditor219 id: avatarEditor
@@ -221,6 +221,7 @@
221 contact: contactEditor.contact221 contact: contactEditor.contact
222 height: implicitHeight222 height: implicitHeight
223 width: implicitWidth223 width: implicitWidth
224 anchors.verticalCenter: editEditor.verticalCenter
224 }225 }
225226
226 ContactDetailNameEditor {227 ContactDetailNameEditor {
@@ -232,6 +233,7 @@
232 }233 }
233 }234 }
234235
236
235 ContactDetailPhoneNumbersEditor {237 ContactDetailPhoneNumbersEditor {
236 id: phonesEditor238 id: phonesEditor
237 objectName: "phones"239 objectName: "phones"
@@ -301,8 +303,6 @@
301 left: parent.left303 left: parent.left
302 right: parent.right304 right: parent.right
303 }305 }
304 height: implicitHeight
305
306 onChanged: {306 onChanged: {
307 if (contactEditor.enabled &&307 if (contactEditor.enabled &&
308 !contactEditor.isNewContact &&308 !contactEditor.isNewContact &&
@@ -383,9 +383,13 @@
383 right: parent.right383 right: parent.right
384 margins: units.gu(2)384 margins: units.gu(2)
385 }385 }
386 onClicked: {386 action: Action {
387 var dialog = PopupUtils.open(removeContactDialog, null)387 enabled: contactEditor.active && deleteButton.visible
388 dialog.contacts = [contactEditor.contact]388 shortcut: "Ctrl+Delete"
389 onTriggered: {
390 var dialog = PopupUtils.open(removeContactDialog, null)
391 dialog.contacts = [contactEditor.contact]
392 }
389 }393 }
390 }394 }
391395
@@ -410,8 +414,8 @@
410 }414 }
411 }415 }
412416
413 Component.onCompleted: {417 onActiveChanged: {
414 if (!enabled) {418 if (!active) {
415 return419 return
416 }420 }
417421
@@ -475,10 +479,14 @@
475 }479 }
476480
477 // hide virtual keyboard if necessary481 // hide virtual keyboard if necessary
478 Component.onCompleted: Qt.inputMethod.hide()482 Component.onCompleted: {
483 contactEditor.enabled = false
484 Qt.inputMethod.hide()
485 }
479486
480 // WORKAROUND: SDK element crash if pop the page where the dialog was created487 // WORKAROUND: SDK element crash if pop the page where the dialog was created
481 Component.onDestruction: {488 Component.onDestruction: {
489 contactEditor.enabled = true
482 if (popPages) {490 if (popPages) {
483 if (contactEditor.pageStack.removePages) {491 if (contactEditor.pageStack.removePages) {
484 contactEditor.pageStack.removePages(contactEditor)492 contactEditor.pageStack.removePages(contactEditor)
485493
=== modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/TextInputDetail.qml'
--- src/imports/Ubuntu/AddressBook/ContactEditor/TextInputDetail.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactEditor/TextInputDetail.qml 2015-12-04 15:09:43 +0000
@@ -25,7 +25,11 @@
25FocusScope {25FocusScope {
26 id: root26 id: root
2727
28 //WORKAROUND: SDK does not allow us to disable focus for items due bug: #1514822
29 //because of that we need this
30 readonly property bool _allowFocus: true
28 readonly property bool isTextField: true31 readonly property bool isTextField: true
32
29 property QtObject detail33 property QtObject detail
30 property int field: -134 property int field: -1
31 property variant originalValue: root.detail && (root.field >= 0) ? root.detail.value(root.field) : null35 property variant originalValue: root.detail && (root.field >= 0) ? root.detail.value(root.field) : null
@@ -67,6 +71,22 @@
67 PhoneNumberField {71 PhoneNumberField {
68 id: field72 id: field
6973
74 //WORKAROUND: Due the SDK bug #1514822, #1514850 we can not disable focus for some items
75 //because of that we keep the focus only for textFields. This will block the user
76 //to use keyboard on "add-field" combo box and some other functionalities
77 function forceActiveFocusForNextField(keyEvent)
78 {
79 var backward = (keyEvent.modifiers & Qt.ShiftModifier)
80 var next = field.nextItemInFocusChain(!backward)
81 // only focus on TextInputDetails
82 while (!next || !next.hasOwnProperty("isTextField")) {
83 next = next.nextItemInFocusChain(!backward)
84 }
85 if (next) {
86 next.forceActiveFocus()
87 }
88 }
89
70 anchors.fill: parent90 anchors.fill: parent
71 defaultRegion: PhoneUtils.defaultRegion91 defaultRegion: PhoneUtils.defaultRegion
72 autoFormat: false92 autoFormat: false
@@ -93,15 +113,9 @@
93 family: "Ubuntu"113 family: "Ubuntu"
94 pixelSize: activeFocus ? FontUtils.sizeToPixels("large") : FontUtils.sizeToPixels("medium")114 pixelSize: activeFocus ? FontUtils.sizeToPixels("large") : FontUtils.sizeToPixels("medium")
95 }115 }
96 Keys.onReturnPressed: {116
97 var next = field.nextItemInFocusChain(true)117 Keys.onReturnPressed: forceActiveFocusForNextField(event)
98 // only focus on TextInputDetails118 Keys.onTabPressed: forceActiveFocusForNextField(event)
99 while (!next || !next.hasOwnProperty("isTextField")) {119 Keys.onBacktabPressed: forceActiveFocusForNextField(event)
100 next = next.nextItemInFocusChain(true)
101 }
102 if (next) {
103 next.forceActiveFocus()
104 }
105 }
106 }120 }
107}121}
108122
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/ActionButton.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/ActionButton.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/ActionButton.qml 2015-12-04 15:09:43 +0000
@@ -30,5 +30,6 @@
30 anchors.centerIn: parent30 anchors.centerIn: parent
31 height: root.iconSize31 height: root.iconSize
32 width: root.iconSize32 width: root.iconSize
33 color: root.activeFocus ? UbuntuColors.orange : "gray"
33 }34 }
34}35}
3536
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/BasicFieldView.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/BasicFieldView.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/BasicFieldView.qml 2015-12-04 15:09:43 +0000
@@ -27,6 +27,8 @@
27 property variant fields: null27 property variant fields: null
28 property int parentIndex: -128 property int parentIndex: -1
2929
30 focus: false
31 activeFocusOnTab: false
30 implicitHeight: typeLabel.height + fieldValues.height + units.gu(2)32 implicitHeight: typeLabel.height + fieldValues.height + units.gu(2)
3133
32 Column {34 Column {
3335
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/ContactDetailAvatarView.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/ContactDetailAvatarView.qml 2015-11-16 20:12:41 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/ContactDetailAvatarView.qml 2015-12-04 15:09:43 +0000
@@ -29,6 +29,8 @@
2929
30 implicitHeight: units.gu(12)30 implicitHeight: units.gu(12)
31 implicitWidth: parent.width31 implicitWidth: parent.width
32 activeFocusOnTab: false
33 focus: false
3234
33 Connections {35 Connections {
34 id: connections36 id: connections
3537
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/ContactDetailGroupWithTypeView.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/ContactDetailGroupWithTypeView.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/ContactDetailGroupWithTypeView.qml 2015-12-04 15:09:43 +0000
@@ -18,8 +18,7 @@
18import QtContacts 5.0 as QtContacts18import QtContacts 5.0 as QtContacts
1919
20import Ubuntu.Components 1.320import Ubuntu.Components 1.3
21import Ubuntu.Components.ListItems 1.3 as ListItem21import Ubuntu.Components.ListItems 1.3
22
23import Ubuntu.AddressBook.Base 0.122import Ubuntu.AddressBook.Base 0.1
2423
25ContactDetailGroupWithTypeBase {24ContactDetailGroupWithTypeBase {
@@ -29,25 +28,18 @@
29 signal actionTrigerred(string actionName, QtObject detail)28 signal actionTrigerred(string actionName, QtObject detail)
3029
31 showEmpty: false30 showEmpty: false
32 headerDelegate: ListItem.Empty {31 headerDelegate: Label {
33 highlightWhenPressed: false32 id: header
3433
35 divider.anchors.leftMargin: units.gu(2)34 width: root.width - units.gu(4)
36 divider.anchors.rightMargin: units.gu(2)35 x: units.gu(2)
37 width: root.width36 height: units.gu(4)
38 height: units.gu(5)37 text: root.title
39 Label {38 // style
40 anchors {39 fontSize: "medium"
41 verticalCenter: parent.verticalCenter40 verticalAlignment: Text.AlignVCenter
42 left: parent.left41 ThinDivider {
43 right: parent.right42 anchors.bottom: parent.bottom
44 margins: units.gu(2)
45 }
46
47 text: root.title
48
49 // style
50 fontSize: "medium"
51 }43 }
52 }44 }
5345
5446
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/ContactDetailNameView.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/ContactDetailNameView.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/ContactDetailNameView.qml 2015-12-04 15:09:43 +0000
@@ -25,7 +25,8 @@
2525
26 detail: root.contact ? root.contact.name : null26 detail: root.contact ? root.contact.name : null
27 implicitHeight: label.paintedHeight + (label.anchors.margins * 2)27 implicitHeight: label.paintedHeight + (label.anchors.margins * 2)
2828 activeFocusOnTab: false
29 focus: false
2930
30 Label {31 Label {
31 id: label32 id: label
3233
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/ContactDetailSyncTargetView.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/ContactDetailSyncTargetView.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/ContactDetailSyncTargetView.qml 2015-12-04 15:09:43 +0000
@@ -50,6 +50,7 @@
50 defaultIcon: "image://theme/contact-group"50 defaultIcon: "image://theme/contact-group"
51 detailType: ContactDetail.SyncTarget51 detailType: ContactDetail.SyncTarget
52 typeModel: null52 typeModel: null
53 activeFocusOnTab: false
5354
54 fields: [ SyncTarget.SyncTarget ]55 fields: [ SyncTarget.SyncTarget ]
5556
@@ -76,7 +77,7 @@
7677
77 height: implicitHeight78 height: implicitHeight
78 width: root.width79 width: root.width
7980 activeFocusOnTab: false
80 onClicked: root.actionTrigerred(root.defaultAction.name, detail)81 onClicked: root.actionTrigerred(root.defaultAction.name, detail)
8182
82 function overrideValue(detail, field)83 function overrideValue(detail, field)
8384
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/ContactDetailWithTypeView.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/ContactDetailWithTypeView.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/ContactDetailWithTypeView.qml 2015-12-04 15:09:43 +0000
@@ -43,6 +43,8 @@
43 return detail.value(field)43 return detail.value(field)
44 }44 }
4545
46 activeFocusOnTab: icon.visible
47 focus: false
46 implicitHeight: view.implicitHeight48 implicitHeight: view.implicitHeight
47 onIsReadyChanged: populateValues()49 onIsReadyChanged: populateValues()
4850
@@ -78,5 +80,7 @@
78 width: root.action && (root.action.iconName !== "") ? units.gu(2.5) : 080 width: root.action && (root.action.iconName !== "") ? units.gu(2.5) : 0
79 height: width81 height: width
80 name: root.action ? root.action.iconName : ""82 name: root.action ? root.action.iconName : ""
83 color: root.activeFocus ? UbuntuColors.orange : "gray"
84 visible: width > 0
81 }85 }
82}86}
8387
=== modified file 'src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml'
--- src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml 2015-11-16 15:44:43 +0000
+++ src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml 2015-12-04 15:09:43 +0000
@@ -41,6 +41,7 @@
41 }41 }
42 }42 }
4343
44 focus: false
44 title: contact ? ContactsJS.formatToDisplay(contact, i18n.dtr("address-book-app", "No name")) : ""45 title: contact ? ContactsJS.formatToDisplay(contact, i18n.dtr("address-book-app", "No name")) : ""
4546
46 Connections {47 Connections {
4748
=== modified file 'src/imports/Ubuntu/Contacts/ContactDelegate.qml'
--- src/imports/Ubuntu/Contacts/ContactDelegate.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/Contacts/ContactDelegate.qml 2015-12-04 15:09:43 +0000
@@ -32,6 +32,7 @@
32 signal clicked(int index, QtObject contact)32 signal clicked(int index, QtObject contact)
33 signal pressAndHold(int index, QtObject contact)33 signal pressAndHold(int index, QtObject contact)
3434
35 focus: false
35 implicitHeight: defaultHeight36 implicitHeight: defaultHeight
36 width: parent ? parent.width : 037 width: parent ? parent.width : 0
3738
3839
=== modified file 'src/imports/Ubuntu/Contacts/ContactListView.qml'
--- src/imports/Ubuntu/Contacts/ContactListView.qml 2015-11-16 22:12:29 +0000
+++ src/imports/Ubuntu/Contacts/ContactListView.qml 2015-12-04 15:09:43 +0000
@@ -42,7 +42,7 @@
42 }42 }
43 \endqml43 \endqml
44*/44*/
45Item {45FocusScope {
46 id: root46 id: root
4747
48 readonly property alias view: view48 readonly property alias view: view
@@ -202,12 +202,6 @@
202 */202 */
203 property bool showAddNewButton: false203 property bool showAddNewButton: false
204 /*!204 /*!
205 \qmlproperty bool prepareNewContact
206
207 This property holds if space for a draft new contact should be made available or not
208 */
209 property bool prepareNewContact: false
210 /*!
211 \qmlproperty bool showNewContact205 \qmlproperty bool showNewContact
212206
213 This property holds if a draft new contact should be visible or not207 This property holds if a draft new contact should be visible or not
@@ -253,6 +247,10 @@
253247
254 property var _busyDialog: null248 property var _busyDialog: null
255249
250 //WORKAROUND: SDK does not allow us to disable focus for items due bug: #1514822
251 //because of that we need this
252 property bool _allowFocus: true
253
256 /*!254 /*!
257 This handler is called when the selection mode is finished without be canceled255 This handler is called when the selection mode is finished without be canceled
258 */256 */
@@ -372,6 +370,8 @@
372 buteoSync.startSyncByCategory("contacts")370 buteoSync.startSyncByCategory("contacts")
373 }371 }
374372
373 focus: true
374
375 ContactSimpleListView {375 ContactSimpleListView {
376 id: view376 id: view
377377
@@ -401,6 +401,7 @@
401 }401 }
402 anchors.fill: parent402 anchors.fill: parent
403403
404
404 // WORKAROUND: The SDK header causes the contactY to move to a wrong postion405 // WORKAROUND: The SDK header causes the contactY to move to a wrong postion
405 // calling the positionViewAtBeginning after the list created fix that406 // calling the positionViewAtBeginning after the list created fix that
406 Timer {407 Timer {
@@ -418,15 +419,18 @@
418 right: parent.right419 right: parent.right
419 }420 }
420421
421 Connections {422 Binding {
422 target: root423 target: view
423 onPrepareNewContactChanged: {424 property: 'contentY'
424 if (root.prepareNewContact) {425 value: -view.headerItem.height
425 view.contentY = Qt.binding(function() {return -view.headerItem.height});426 when: root.showNewContact
426 } else {427 }
427 view.contentY = view.contentY;428
428 }429 Binding {
429 }430 target: view
431 property: 'currentIndex'
432 value: -1
433 when: root.showNewContact
430 }434 }
431435
432 // AddNewButton436 // AddNewButton
@@ -455,10 +459,9 @@
455 }459 }
456 }460 }
457 selected: true461 selected: true
458 visible: root.prepareNewContact462 visible: root.showNewContact
459 height: root.prepareNewContact ? defaultHeight : 0463 height: root.showNewContact ? defaultHeight : 0
460 Behavior on height {UbuntuNumberAnimation {}}464 Behavior on height {UbuntuNumberAnimation {}}
461 opacity: root.showNewContact ? 1.0 : 0.0
462 }465 }
463466
464 Column {467 Column {
@@ -624,4 +627,23 @@
624 !view.favouritesIsSelected &&627 !view.favouritesIsSelected &&
625 !isSearching ? sourceFile : ""628 !isSearching ? sourceFile : ""
626 }629 }
630
631 Keys.onUpPressed: {
632 //WORKAROUND: SDK does not allow us to disable focus for items due bug: #1514822
633 //because of that we need this
634 if (view.currentIndex == 0) {
635 pageStack._nextItemInFocusChain(view, false)
636 } else {
637 view.currentIndex -= 1
638 }
639 }
640 Keys.onDownPressed: {
641 //WORKAROUND: SDK does not allow us to disable focus for items due bug: #1514822
642 //because of that we need this
643 if (view.currentIndex == (view.count - 1)) {
644 //DO nothing
645 } else {
646 view.currentIndex += 1
647 }
648 }
627}649}
628650
=== modified file 'src/imports/Ubuntu/Contacts/ContactSimpleListView.qml'
--- src/imports/Ubuntu/Contacts/ContactSimpleListView.qml 2015-11-16 22:12:29 +0000
+++ src/imports/Ubuntu/Contacts/ContactSimpleListView.qml 2015-12-04 15:09:43 +0000
@@ -204,7 +204,8 @@
204 */204 */
205 function positionViewAtContact(contact)205 function positionViewAtContact(contact)
206 {206 {
207 positionViewAtIndex(getIndex(contact), ListView.Center)207 currentIndex = getIndex(contact)
208 positionViewAtIndex(currentIndex, ListView.Center)
208 }209 }
209210
210 /*!211 /*!
@@ -213,7 +214,9 @@
213 */214 */
214 function _fetchContact(index, contact)215 function _fetchContact(index, contact)
215 {216 {
216 contactFetch.fetchContact(contact.contactId)217 if (contact) {
218 contactFetch.fetchContact(contact.contactId)
219 }
217 }220 }
218221
219 function _updateSwipeState(item)222 function _updateSwipeState(item)
@@ -235,7 +238,6 @@
235 }238 }
236239
237 highlightFollowsCurrentItem: true240 highlightFollowsCurrentItem: true
238 currentIndex: -1
239 section {241 section {
240 property: showSections ? "contact.tag.tag" : ""242 property: showSections ? "contact.tag.tag" : ""
241 criteria: ViewSection.FirstCharacter243 criteria: ViewSection.FirstCharacter
@@ -255,7 +257,6 @@
255 dirtyModel.restart()257 dirtyModel.restart()
256 }258 }
257259
258 onFlickStarted: view.currentIndex = -1
259 listDelegate: ContactDelegate {260 listDelegate: ContactDelegate {
260 id: contactDelegate261 id: contactDelegate
261262
@@ -270,6 +271,7 @@
270 width: parent.width271 width: parent.width
271 selected: (contactListView.multiSelectionEnabled && contactListView.isSelected(contactDelegate))272 selected: (contactListView.multiSelectionEnabled && contactListView.isSelected(contactDelegate))
272 || (contactListView.highlightSelected && (contactListView.currentIndex == index))273 || (contactListView.highlightSelected && (contactListView.currentIndex == index))
274 selectedColor: contactListView.parent.activeFocus && !contactListView.isInSelectionMode ? UbuntuColors.orange : "#E6E6E6"
273 selectionMode: contactListView.isInSelectionMode275 selectionMode: contactListView.isInSelectionMode
274 defaultAvatarUrl: contactListView.defaultAvatarImageUrl276 defaultAvatarUrl: contactListView.defaultAvatarImageUrl
275 isCurrentItem: ListView.isCurrentItem277 isCurrentItem: ListView.isCurrentItem
@@ -371,13 +373,4 @@
371 property int pendingTargetIndex: 0373 property int pendingTargetIndex: 0
372 property variant pendingTargetMode: null374 property variant pendingTargetMode: null
373 }375 }
374
375 Connections {
376 target: Qt.application
377 onActiveChanged: {
378 if (!Qt.application.active) {
379 currentIndex = -1
380 }
381 }
382 }
383}376}
384377
=== modified file 'src/imports/Ubuntu/Contacts/FastScroll.qml'
--- src/imports/Ubuntu/Contacts/FastScroll.qml 2015-10-26 13:18:11 +0000
+++ src/imports/Ubuntu/Contacts/FastScroll.qml 2015-12-04 15:09:43 +0000
@@ -71,19 +71,11 @@
71 }71 }
72 }72 }
7373
74 Connections {
75 target: listView
76 onCurrentIndexChanged: {
77 if (currentIndex != -1) {
78 rail.opacity = 0.0
79 }
80 }
81 }
8274
83 Rectangle {75 Rectangle {
84 id: magnified76 id: magnified
8577
86 color: Theme.palette.normal.overlay78 color: Theme.palette.normal.foreground
87 radius: height * 0.379 radius: height * 0.3
88 height: pinSize * 280 height: pinSize * 2
89 width: height81 width: height
@@ -99,6 +91,7 @@
99 }91 }
10092
101 Label {93 Label {
94 color: "white"
102 anchors.fill: parent95 anchors.fill: parent
103 horizontalAlignment: Text.AlignHCenter96 horizontalAlignment: Text.AlignHCenter
104 verticalAlignment: Text.AlignVCenter97 verticalAlignment: Text.AlignVCenter
@@ -141,8 +134,7 @@
141 id: rail134 id: rail
142135
143 property bool isVisible: root.enabled &&136 property bool isVisible: root.enabled &&
144 (listView.flicking || dragArea.pressed) &&137 (listView.flicking || dragArea.pressed)
145 (listView.currentIndex == -1)
146 anchors {138 anchors {
147 right: parent.right139 right: parent.right
148 rightMargin: units.gu(2)140 rightMargin: units.gu(2)

Subscribers

People subscribed via source and target branches