Merge lp:~boiko/messaging-app/compose_bar into lp:messaging-app
- compose_bar
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 486 |
Proposed branch: | lp:~boiko/messaging-app/compose_bar |
Merge into: | lp:messaging-app |
Prerequisite: | lp:~tiagosh/messaging-app/update-sim-dialogs |
Diff against target: |
1193 lines (+655/-449) 7 files modified
src/qml/ComposeBar.qml (+312/-0) src/qml/Messages.qml (+56/-448) src/qml/MessagesHeader.qml (+1/-1) src/qml/ThumbnailContact.qml (+106/-0) src/qml/ThumbnailImage.qml (+49/-0) src/qml/ThumbnailUnknown.qml (+45/-0) src/qml/TransparentButton.qml (+86/-0) |
To merge this branch: | bzr merge lp:~boiko/messaging-app/compose_bar |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Tiago Salem Herrmann (community) | Needs Fixing | ||
Review via email: mp+278208@code.launchpad.net |
Commit message
Move the bottom part of Messages view to a separate QML file for better code readability.
Description of the change
Move the bottom part of Messages view to a separate QML file for better code readability.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 444. By Gustavo Pichorim Boiko
-
Merge latest changes from trunk.
- 445. By Gustavo Pichorim Boiko
-
Remove unused include.
- 446. By Gustavo Pichorim Boiko
-
Add missing thumbnail files.
- 447. By Gustavo Pichorim Boiko
-
Merge latest changes from trunk.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:445
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:447
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 448. By Gustavo Pichorim Boiko
-
Merge latest changes from trunk.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:448
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Tiago Salem Herrmann (tiagosh) : | # |
- 449. By Gustavo Pichorim Boiko
-
Fix import version.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:449
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 450. By Gustavo Pichorim Boiko
-
Add missing copyright.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:450
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Tiago Salem Herrmann (tiagosh) : | # |
- 451. By Gustavo Pichorim Boiko
-
Add missing pressAndHold() signal and make use of it
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:451
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 452. By Gustavo Pichorim Boiko
-
Merge trunk.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:452
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 453. By Gustavo Pichorim Boiko
-
Merge trunk.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:453
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === added file 'src/qml/ComposeBar.qml' | |||
2 | --- src/qml/ComposeBar.qml 1970-01-01 00:00:00 +0000 | |||
3 | +++ src/qml/ComposeBar.qml 2015-12-08 17:14:16 +0000 | |||
4 | @@ -0,0 +1,312 @@ | |||
5 | 1 | /* | ||
6 | 2 | * Copyright 2012-2015 Canonical Ltd. | ||
7 | 3 | * | ||
8 | 4 | * This file is part of messaging-app. | ||
9 | 5 | * | ||
10 | 6 | * messaging-app is free software; you can redistribute it and/or modify | ||
11 | 7 | * it under the terms of the GNU General Public License as published by | ||
12 | 8 | * the Free Software Foundation; version 3. | ||
13 | 9 | * | ||
14 | 10 | * messaging-app is distributed in the hope that it will be useful, | ||
15 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | 13 | * GNU General Public License for more details. | ||
18 | 14 | * | ||
19 | 15 | * You should have received a copy of the GNU General Public License | ||
20 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | 17 | */ | ||
22 | 18 | |||
23 | 19 | import QtQuick 2.0 | ||
24 | 20 | import Ubuntu.Components 1.3 | ||
25 | 21 | import Ubuntu.Components.ListItems 1.3 as ListItem | ||
26 | 22 | import Ubuntu.Components.Popups 1.3 | ||
27 | 23 | import Ubuntu.Content 0.1 | ||
28 | 24 | import Ubuntu.Telephony 0.1 | ||
29 | 25 | |||
30 | 26 | Item { | ||
31 | 27 | id: composeBar | ||
32 | 28 | |||
33 | 29 | property bool showContents: true | ||
34 | 30 | property int maxHeight: textEntry.height + units.gu(2) | ||
35 | 31 | property variant attachments: [] | ||
36 | 32 | property bool canSend: true | ||
37 | 33 | property alias text: messageTextArea.text | ||
38 | 34 | |||
39 | 35 | signal sendRequested(string text, var attachments) | ||
40 | 36 | |||
41 | 37 | // internal properties | ||
42 | 38 | property int _activeAttachmentIndex: -1 | ||
43 | 39 | property int _defaultHeight: textEntry.height + units.gu(2) | ||
44 | 40 | |||
45 | 41 | function forceFocus() { | ||
46 | 42 | messageTextArea.forceActiveFocus() | ||
47 | 43 | } | ||
48 | 44 | |||
49 | 45 | function reset() { | ||
50 | 46 | textEntry.text = "" | ||
51 | 47 | attachments.clear() | ||
52 | 48 | } | ||
53 | 49 | |||
54 | 50 | function addAttachments(transfer) { | ||
55 | 51 | for (var i = 0; i < transfer.items.length; i++) { | ||
56 | 52 | if (String(transfer.items[i].text).length > 0) { | ||
57 | 53 | composeBar.text = String(transfer.items[i].text) | ||
58 | 54 | continue | ||
59 | 55 | } | ||
60 | 56 | var attachment = {} | ||
61 | 57 | if (!startsWith(String(transfer.items[i].url),"file://")) { | ||
62 | 58 | composeBar.text = String(transfer.items[i].url) | ||
63 | 59 | continue | ||
64 | 60 | } | ||
65 | 61 | var filePath = String(transfer.items[i].url).replace('file://', '') | ||
66 | 62 | // get only the basename | ||
67 | 63 | attachment["contentType"] = application.fileMimeType(filePath) | ||
68 | 64 | if (startsWith(attachment["contentType"], "text/vcard") || | ||
69 | 65 | startsWith(attachment["contentType"], "text/x-vcard")) { | ||
70 | 66 | attachment["name"] = "contact.vcf" | ||
71 | 67 | } else { | ||
72 | 68 | attachment["name"] = filePath.split('/').reverse()[0] | ||
73 | 69 | } | ||
74 | 70 | attachment["filePath"] = filePath | ||
75 | 71 | attachments.append(attachment) | ||
76 | 72 | } | ||
77 | 73 | } | ||
78 | 74 | |||
79 | 75 | function formattedTime(time) { | ||
80 | 76 | var d = new Date(0, 0, 0, 0, 0, time) | ||
81 | 77 | return d.getHours() == 0 ? Qt.formatTime(d, "mm:ss") : Qt.formatTime(d, "h:mm:ss") | ||
82 | 78 | } | ||
83 | 79 | |||
84 | 80 | anchors.bottom: isSearching ? parent.bottom : keyboard.top | ||
85 | 81 | anchors.left: parent.left | ||
86 | 82 | anchors.right: parent.right | ||
87 | 83 | height: showContents ? Math.min(_defaultHeight, maxHeight) : 0 | ||
88 | 84 | visible: showContents | ||
89 | 85 | clip: true | ||
90 | 86 | |||
91 | 87 | Behavior on height { | ||
92 | 88 | UbuntuNumberAnimation { } | ||
93 | 89 | } | ||
94 | 90 | |||
95 | 91 | MouseArea { | ||
96 | 92 | anchors.fill: parent | ||
97 | 93 | onClicked: { | ||
98 | 94 | forceFocus() | ||
99 | 95 | } | ||
100 | 96 | } | ||
101 | 97 | |||
102 | 98 | ListModel { | ||
103 | 99 | id: attachments | ||
104 | 100 | } | ||
105 | 101 | |||
106 | 102 | Component { | ||
107 | 103 | id: attachmentPopover | ||
108 | 104 | |||
109 | 105 | Popover { | ||
110 | 106 | id: popover | ||
111 | 107 | Column { | ||
112 | 108 | id: containerLayout | ||
113 | 109 | anchors { | ||
114 | 110 | left: parent.left | ||
115 | 111 | top: parent.top | ||
116 | 112 | right: parent.right | ||
117 | 113 | } | ||
118 | 114 | ListItem.Standard { | ||
119 | 115 | text: i18n.tr("Remove") | ||
120 | 116 | onClicked: { | ||
121 | 117 | attachments.remove(_activeAttachmentIndex) | ||
122 | 118 | PopupUtils.close(popover) | ||
123 | 119 | } | ||
124 | 120 | } | ||
125 | 121 | } | ||
126 | 122 | Component.onDestruction: _activeAttachmentIndex = -1 | ||
127 | 123 | } | ||
128 | 124 | } | ||
129 | 125 | |||
130 | 126 | ListItem.ThinDivider { | ||
131 | 127 | anchors.top: parent.top | ||
132 | 128 | } | ||
133 | 129 | |||
134 | 130 | Row { | ||
135 | 131 | id: leftSideActions | ||
136 | 132 | |||
137 | 133 | width: childrenRect.width | ||
138 | 134 | height: childrenRect.height | ||
139 | 135 | |||
140 | 136 | anchors { | ||
141 | 137 | left: parent.left | ||
142 | 138 | leftMargin: units.gu(2) | ||
143 | 139 | verticalCenter: sendButton.verticalCenter | ||
144 | 140 | } | ||
145 | 141 | spacing: units.gu(2) | ||
146 | 142 | |||
147 | 143 | PictureImport { | ||
148 | 144 | id: pictureImporter | ||
149 | 145 | |||
150 | 146 | onPictureReceived: { | ||
151 | 147 | var attachment = {} | ||
152 | 148 | var filePath = String(pictureUrl).replace('file://', '') | ||
153 | 149 | attachment["contentType"] = application.fileMimeType(filePath) | ||
154 | 150 | attachment["name"] = filePath.split('/').reverse()[0] | ||
155 | 151 | attachment["filePath"] = filePath | ||
156 | 152 | attachments.append(attachment) | ||
157 | 153 | textEntry.forceActiveFocus() | ||
158 | 154 | } | ||
159 | 155 | } | ||
160 | 156 | |||
161 | 157 | TransparentButton { | ||
162 | 158 | id: attachButton | ||
163 | 159 | objectName: "attachButton" | ||
164 | 160 | iconName: "camera-app-symbolic" | ||
165 | 161 | onClicked: { | ||
166 | 162 | Qt.inputMethod.hide() | ||
167 | 163 | pictureImporter.requestNewPicture() | ||
168 | 164 | } | ||
169 | 165 | } | ||
170 | 166 | } | ||
171 | 167 | |||
172 | 168 | StyledItem { | ||
173 | 169 | id: textEntry | ||
174 | 170 | property alias text: messageTextArea.text | ||
175 | 171 | property alias inputMethodComposing: messageTextArea.inputMethodComposing | ||
176 | 172 | property int fullSize: attachmentThumbnails.height + messageTextArea.height | ||
177 | 173 | style: Theme.createStyleComponent("TextAreaStyle.qml", textEntry) | ||
178 | 174 | anchors { | ||
179 | 175 | topMargin: units.gu(1) | ||
180 | 176 | top: parent.top | ||
181 | 177 | left: leftSideActions.right | ||
182 | 178 | leftMargin: units.gu(2) | ||
183 | 179 | right: sendButton.left | ||
184 | 180 | rightMargin: units.gu(2) | ||
185 | 181 | } | ||
186 | 182 | height: attachments.count !== 0 ? fullSize + units.gu(1.5) : fullSize | ||
187 | 183 | onActiveFocusChanged: { | ||
188 | 184 | if(activeFocus) { | ||
189 | 185 | messageTextArea.forceActiveFocus() | ||
190 | 186 | } else { | ||
191 | 187 | focus = false | ||
192 | 188 | } | ||
193 | 189 | } | ||
194 | 190 | focus: false | ||
195 | 191 | MouseArea { | ||
196 | 192 | anchors.fill: parent | ||
197 | 193 | onClicked: forceFocus() | ||
198 | 194 | } | ||
199 | 195 | Flow { | ||
200 | 196 | id: attachmentThumbnails | ||
201 | 197 | spacing: units.gu(1) | ||
202 | 198 | anchors{ | ||
203 | 199 | left: parent.left | ||
204 | 200 | right: parent.right | ||
205 | 201 | top: parent.top | ||
206 | 202 | topMargin: units.gu(1) | ||
207 | 203 | leftMargin: units.gu(1) | ||
208 | 204 | rightMargin: units.gu(1) | ||
209 | 205 | } | ||
210 | 206 | height: childrenRect.height | ||
211 | 207 | |||
212 | 208 | Repeater { | ||
213 | 209 | model: attachments | ||
214 | 210 | delegate: Loader { | ||
215 | 211 | id: loader | ||
216 | 212 | height: units.gu(8) | ||
217 | 213 | source: { | ||
218 | 214 | var contentType = getContentType(filePath) | ||
219 | 215 | console.log(contentType) | ||
220 | 216 | switch(contentType) { | ||
221 | 217 | case ContentType.Contacts: | ||
222 | 218 | return Qt.resolvedUrl("ThumbnailContact.qml") | ||
223 | 219 | case ContentType.Pictures: | ||
224 | 220 | return Qt.resolvedUrl("ThumbnailImage.qml") | ||
225 | 221 | case ContentType.Unknown: | ||
226 | 222 | return Qt.resolvedUrl("ThumbnailUnknown.qml") | ||
227 | 223 | default: | ||
228 | 224 | console.log("unknown content Type") | ||
229 | 225 | } | ||
230 | 226 | } | ||
231 | 227 | onStatusChanged: { | ||
232 | 228 | if (status == Loader.Ready) { | ||
233 | 229 | item.index = index | ||
234 | 230 | item.filePath = filePath | ||
235 | 231 | } | ||
236 | 232 | } | ||
237 | 233 | |||
238 | 234 | Connections { | ||
239 | 235 | target: loader.status == Loader.Ready ? loader.item : null | ||
240 | 236 | ignoreUnknownSignals: true | ||
241 | 237 | onPressAndHold: { | ||
242 | 238 | Qt.inputMethod.hide() | ||
243 | 239 | _activeAttachmentIndex = target.index | ||
244 | 240 | PopupUtils.open(attachmentPopover, parent) | ||
245 | 241 | } | ||
246 | 242 | } | ||
247 | 243 | } | ||
248 | 244 | } | ||
249 | 245 | } | ||
250 | 246 | |||
251 | 247 | ListItem.ThinDivider { | ||
252 | 248 | id: divider | ||
253 | 249 | |||
254 | 250 | anchors { | ||
255 | 251 | left: parent.left | ||
256 | 252 | right: parent.right | ||
257 | 253 | top: attachmentThumbnails.bottom | ||
258 | 254 | margins: units.gu(0.5) | ||
259 | 255 | } | ||
260 | 256 | visible: attachments.count > 0 | ||
261 | 257 | } | ||
262 | 258 | |||
263 | 259 | TextArea { | ||
264 | 260 | id: messageTextArea | ||
265 | 261 | objectName: "messageTextArea" | ||
266 | 262 | anchors { | ||
267 | 263 | top: attachments.count == 0 ? textEntry.top : attachmentThumbnails.bottom | ||
268 | 264 | left: parent.left | ||
269 | 265 | right: parent.right | ||
270 | 266 | } | ||
271 | 267 | // this value is to avoid letter being cut off | ||
272 | 268 | height: units.gu(4.3) | ||
273 | 269 | style: LocalTextAreaStyle {} | ||
274 | 270 | autoSize: true | ||
275 | 271 | maximumLineCount: attachments.count == 0 ? 8 : 4 | ||
276 | 272 | placeholderText: { | ||
277 | 273 | if (telepathyHelper.ready) { | ||
278 | 274 | var account = telepathyHelper.accountForId(presenceRequest.accountId) | ||
279 | 275 | if (account && | ||
280 | 276 | (presenceRequest.type != PresenceRequest.PresenceTypeUnknown && | ||
281 | 277 | presenceRequest.type != PresenceRequest.PresenceTypeUnset) && | ||
282 | 278 | account.protocolInfo.serviceName !== "") { | ||
283 | 279 | console.log(presenceRequest.accountId) | ||
284 | 280 | console.log(presenceRequest.type) | ||
285 | 281 | return account.protocolInfo.serviceName | ||
286 | 282 | } | ||
287 | 283 | } | ||
288 | 284 | return i18n.tr("Write a message...") | ||
289 | 285 | } | ||
290 | 286 | focus: textEntry.focus | ||
291 | 287 | font.family: "Ubuntu" | ||
292 | 288 | font.pixelSize: FontUtils.sizeToPixels("medium") | ||
293 | 289 | color: "#5d5d5d" | ||
294 | 290 | } | ||
295 | 291 | } | ||
296 | 292 | |||
297 | 293 | TransparentButton { | ||
298 | 294 | id: sendButton | ||
299 | 295 | objectName: "sendButton" | ||
300 | 296 | anchors.verticalCenter: textEntry.verticalCenter | ||
301 | 297 | anchors.right: parent.right | ||
302 | 298 | anchors.rightMargin: units.gu(2) | ||
303 | 299 | iconSource: Qt.resolvedUrl("./assets/send.svg") | ||
304 | 300 | enabled: (canSend && (textEntry.text != "" || textEntry.inputMethodComposing || attachments.count > 0)) | ||
305 | 301 | |||
306 | 302 | onClicked: { | ||
307 | 303 | // make sure we flush everything we have prepared in the OSK preedit | ||
308 | 304 | Qt.inputMethod.commit(); | ||
309 | 305 | if (textEntry.text == "" && attachments.count == 0) { | ||
310 | 306 | return | ||
311 | 307 | } | ||
312 | 308 | |||
313 | 309 | composeBar.sendRequested(textEntry.text, attachments) | ||
314 | 310 | } | ||
315 | 311 | } | ||
316 | 312 | } | ||
317 | 0 | 313 | ||
318 | === modified file 'src/qml/Messages.qml' | |||
319 | --- src/qml/Messages.qml 2015-12-07 17:55:17 +0000 | |||
320 | +++ src/qml/Messages.qml 2015-12-08 17:14:16 +0000 | |||
321 | @@ -1,5 +1,5 @@ | |||
322 | 1 | /* | 1 | /* |
324 | 2 | * Copyright 2012, 2013, 2014 Canonical Ltd. | 2 | * Copyright 2012-2015 Canonical Ltd. |
325 | 3 | * | 3 | * |
326 | 4 | * This file is part of messaging-app. | 4 | * This file is part of messaging-app. |
327 | 5 | * | 5 | * |
328 | @@ -272,32 +272,6 @@ | |||
329 | 272 | sections.selectedIndex: getSelectedIndex() | 272 | sections.selectedIndex: getSelectedIndex() |
330 | 273 | } | 273 | } |
331 | 274 | 274 | ||
332 | 275 | |||
333 | 276 | function addAttachmentsToModel(transfer) { | ||
334 | 277 | for (var i in transfer.items) { | ||
335 | 278 | if (String(transfer.items[i].text).length > 0) { | ||
336 | 279 | messages.text = String(transfer.items[i].text) | ||
337 | 280 | continue | ||
338 | 281 | } | ||
339 | 282 | var attachment = {} | ||
340 | 283 | if (!startsWith(String(transfer.items[i].url),"file://")) { | ||
341 | 284 | messages.text = String(transfer.items[i].url) | ||
342 | 285 | continue | ||
343 | 286 | } | ||
344 | 287 | var filePath = String(transfer.items[i].url).replace('file://', '') | ||
345 | 288 | // get only the basename | ||
346 | 289 | attachment["contentType"] = application.fileMimeType(filePath) | ||
347 | 290 | if (startsWith(attachment["contentType"], "text/vcard") || | ||
348 | 291 | startsWith(attachment["contentType"], "text/x-vcard")) { | ||
349 | 292 | attachment["name"] = "contact.vcf" | ||
350 | 293 | } else { | ||
351 | 294 | attachment["name"] = filePath.split('/').reverse()[0] | ||
352 | 295 | } | ||
353 | 296 | attachment["filePath"] = filePath | ||
354 | 297 | attachments.append(attachment) | ||
355 | 298 | } | ||
356 | 299 | } | ||
357 | 300 | |||
358 | 301 | function sendMessageNetworkCheck() { | 275 | function sendMessageNetworkCheck() { |
359 | 302 | if (messages.account.simLocked) { | 276 | if (messages.account.simLocked) { |
360 | 303 | Qt.inputMethod.hide() | 277 | Qt.inputMethod.hide() |
361 | @@ -500,24 +474,6 @@ | |||
362 | 500 | visible: running | 474 | visible: running |
363 | 501 | } | 475 | } |
364 | 502 | 476 | ||
365 | 503 | ListModel { | ||
366 | 504 | id: attachments | ||
367 | 505 | } | ||
368 | 506 | |||
369 | 507 | PictureImport { | ||
370 | 508 | id: pictureImporter | ||
371 | 509 | |||
372 | 510 | onPictureReceived: { | ||
373 | 511 | var attachment = {} | ||
374 | 512 | var filePath = String(pictureUrl).replace('file://', '') | ||
375 | 513 | attachment["contentType"] = application.fileMimeType(filePath) | ||
376 | 514 | attachment["name"] = filePath.split('/').reverse()[0] | ||
377 | 515 | attachment["filePath"] = filePath | ||
378 | 516 | attachments.append(attachment) | ||
379 | 517 | textEntry.forceActiveFocus() | ||
380 | 518 | } | ||
381 | 519 | } | ||
382 | 520 | |||
383 | 521 | flickable: null | 477 | flickable: null |
384 | 522 | 478 | ||
385 | 523 | property bool isReady: false | 479 | property bool isReady: false |
386 | @@ -560,7 +516,7 @@ | |||
387 | 560 | } | 516 | } |
388 | 561 | } | 517 | } |
389 | 562 | } | 518 | } |
391 | 563 | addAttachmentsToModel(sharedAttachmentsTransfer) | 519 | composeBar.addAttachments(sharedAttachmentsTransfer) |
392 | 564 | } | 520 | } |
393 | 565 | 521 | ||
394 | 566 | onActiveChanged: { | 522 | onActiveChanged: { |
395 | @@ -642,30 +598,6 @@ | |||
396 | 642 | } | 598 | } |
397 | 643 | 599 | ||
398 | 644 | Component { | 600 | Component { |
399 | 645 | id: attachmentPopover | ||
400 | 646 | |||
401 | 647 | Popover { | ||
402 | 648 | id: popover | ||
403 | 649 | Column { | ||
404 | 650 | id: containerLayout | ||
405 | 651 | anchors { | ||
406 | 652 | left: parent.left | ||
407 | 653 | top: parent.top | ||
408 | 654 | right: parent.right | ||
409 | 655 | } | ||
410 | 656 | ListItem.Standard { | ||
411 | 657 | text: i18n.tr("Remove") | ||
412 | 658 | onClicked: { | ||
413 | 659 | attachments.remove(activeAttachmentIndex) | ||
414 | 660 | PopupUtils.close(popover) | ||
415 | 661 | } | ||
416 | 662 | } | ||
417 | 663 | } | ||
418 | 664 | Component.onDestruction: activeAttachmentIndex = -1 | ||
419 | 665 | } | ||
420 | 666 | } | ||
421 | 667 | |||
422 | 668 | Component { | ||
423 | 669 | id: participantsPopover | 601 | id: participantsPopover |
424 | 670 | 602 | ||
425 | 671 | Popover { | 603 | Popover { |
426 | @@ -748,7 +680,7 @@ | |||
427 | 748 | topMargin: units.gu(2) | 680 | topMargin: units.gu(2) |
428 | 749 | left: parent.left | 681 | left: parent.left |
429 | 750 | right: parent.right | 682 | right: parent.right |
431 | 751 | bottom: bottomPanel.top | 683 | bottom: composeBar.top |
432 | 752 | } | 684 | } |
433 | 753 | z: 1 | 685 | z: 1 |
434 | 754 | Behavior on height { | 686 | Behavior on height { |
435 | @@ -1029,386 +961,62 @@ | |||
436 | 1029 | top: screenTop.bottom | 961 | top: screenTop.bottom |
437 | 1030 | left: parent.left | 962 | left: parent.left |
438 | 1031 | right: parent.right | 963 | right: parent.right |
440 | 1032 | bottom: bottomPanel.top | 964 | bottom: composeBar.top |
441 | 1033 | } | 965 | } |
442 | 1034 | } | 966 | } |
443 | 1035 | 967 | ||
820 | 1036 | Item { | 968 | ComposeBar { |
821 | 1037 | id: bottomPanel | 969 | id: composeBar |
822 | 1038 | property int defaultHeight: textEntry.height + units.gu(2) | 970 | anchors { |
823 | 1039 | anchors.bottom: isSearching ? parent.bottom : keyboard.top | 971 | bottom: isSearching ? parent.bottom : keyboard.top |
824 | 1040 | anchors.left: parent.left | 972 | left: parent.left |
825 | 1041 | anchors.right: parent.right | 973 | right: parent.right |
826 | 1042 | height: { | 974 | } |
827 | 1043 | if (selectionMode || (participants.length > 0 && !contactWatcher.interactive)) { | 975 | |
828 | 1044 | return 0 | 976 | showContents: !selectionMode && !isSearching |
829 | 1045 | } else { | 977 | maxHeight: messages.height - keyboard.height - screenTop.y |
830 | 1046 | if (messages.height - keyboard.height - screenTop.y > defaultHeight) { | 978 | text: messages.text |
831 | 1047 | return defaultHeight | 979 | canSend: participants.length > 0 || multiRecipient.recipientCount > 0 || multiRecipient.searchString !== "" |
832 | 1048 | } else { | 980 | |
833 | 1049 | return messages.height - keyboard.height - screenTop.y | 981 | Component.onCompleted: { |
834 | 1050 | } | 982 | // if page is active, it means this is not a bottom edge page |
835 | 1051 | } | 983 | if (messages.active && messages.keyboardFocus && participants.length != 0) { |
836 | 1052 | } | 984 | forceFocus() |
837 | 1053 | visible: !selectionMode && !isSearching | 985 | } |
838 | 1054 | clip: true | 986 | } |
839 | 1055 | MouseArea { | 987 | |
840 | 1056 | anchors.fill: parent | 988 | onSendRequested: { |
841 | 1057 | onClicked: { | 989 | // refresh the recipient list |
842 | 1058 | messageTextArea.forceActiveFocus() | 990 | multiRecipient.focus = false |
843 | 1059 | } | 991 | |
844 | 1060 | } | 992 | if (messages.account && messages.accountId == "") { |
845 | 1061 | 993 | messages.accountId = messages.account.accountId | |
846 | 1062 | Behavior on height { | 994 | messages.head.sections.selectedIndex = Qt.binding(getSelectedIndex) |
847 | 1063 | UbuntuNumberAnimation { } | 995 | } |
848 | 1064 | } | 996 | |
849 | 1065 | 997 | var newAttachments = [] | |
850 | 1066 | ListItem.ThinDivider { | 998 | for (var i = 0; i < attachments.count; i++) { |
851 | 1067 | anchors.top: parent.top | 999 | var attachment = [] |
852 | 1068 | } | 1000 | var item = attachments.get(i) |
853 | 1069 | 1001 | // we dont include smil files. they will be auto generated | |
854 | 1070 | Icon { | 1002 | if (item.contentType.toLowerCase() === "application/smil") { |
855 | 1071 | id: attachButton | 1003 | continue |
856 | 1072 | objectName: "attachButton" | 1004 | } |
857 | 1073 | anchors.left: parent.left | 1005 | attachment.push(item.name) |
858 | 1074 | anchors.leftMargin: units.gu(2) | 1006 | attachment.push(item.contentType) |
859 | 1075 | anchors.verticalCenter: sendButton.verticalCenter | 1007 | attachment.push(item.filePath) |
860 | 1076 | height: units.gu(3) | 1008 | newAttachments.push(attachment) |
861 | 1077 | width: units.gu(3) | 1009 | } |
862 | 1078 | color: "gray" | 1010 | |
863 | 1079 | name: "camera-app-symbolic" | 1011 | var recipients = participantIds.length > 0 ? participantIds : |
864 | 1080 | MouseArea { | 1012 | multiRecipient.recipients |
865 | 1081 | anchors.fill: parent | 1013 | // if sendMessage succeeds it means the message was either sent or |
866 | 1082 | anchors.margins: units.gu(-2) | 1014 | // injected into the history service so the user can retry later |
867 | 1083 | onClicked: { | 1015 | if (sendMessage(text, recipients, newAttachments)) { |
868 | 1084 | Qt.inputMethod.hide() | 1016 | composeBar.reset() |
869 | 1085 | pictureImporter.requestNewPicture() | 1017 | } |
870 | 1086 | } | 1018 | if (eventModel.filter == null) { |
871 | 1087 | } | 1019 | reloadFilters = !reloadFilters |
496 | 1088 | } | ||
497 | 1089 | |||
498 | 1090 | StyledItem { | ||
499 | 1091 | id: textEntry | ||
500 | 1092 | property alias text: messageTextArea.text | ||
501 | 1093 | property alias inputMethodComposing: messageTextArea.inputMethodComposing | ||
502 | 1094 | property int fullSize: attachmentThumbnails.height + messageTextArea.height | ||
503 | 1095 | style: Theme.createStyleComponent("TextAreaStyle.qml", textEntry) | ||
504 | 1096 | anchors.bottomMargin: units.gu(1) | ||
505 | 1097 | anchors.bottom: parent.bottom | ||
506 | 1098 | anchors.left: attachButton.right | ||
507 | 1099 | anchors.leftMargin: units.gu(1) | ||
508 | 1100 | anchors.right: sendButton.left | ||
509 | 1101 | anchors.rightMargin: units.gu(1) | ||
510 | 1102 | height: attachments.count !== 0 ? fullSize + units.gu(1.5) : fullSize | ||
511 | 1103 | onActiveFocusChanged: { | ||
512 | 1104 | if(activeFocus) { | ||
513 | 1105 | messageTextArea.forceActiveFocus() | ||
514 | 1106 | } else { | ||
515 | 1107 | focus = false | ||
516 | 1108 | } | ||
517 | 1109 | } | ||
518 | 1110 | focus: false | ||
519 | 1111 | MouseArea { | ||
520 | 1112 | anchors.fill: parent | ||
521 | 1113 | onClicked: messageTextArea.forceActiveFocus() | ||
522 | 1114 | } | ||
523 | 1115 | Flow { | ||
524 | 1116 | id: attachmentThumbnails | ||
525 | 1117 | spacing: units.gu(1) | ||
526 | 1118 | anchors{ | ||
527 | 1119 | left: parent.left | ||
528 | 1120 | right: parent.right | ||
529 | 1121 | top: parent.top | ||
530 | 1122 | topMargin: units.gu(1) | ||
531 | 1123 | leftMargin: units.gu(1) | ||
532 | 1124 | rightMargin: units.gu(1) | ||
533 | 1125 | } | ||
534 | 1126 | height: childrenRect.height | ||
535 | 1127 | |||
536 | 1128 | Component { | ||
537 | 1129 | id: thumbnailImage | ||
538 | 1130 | UbuntuShape { | ||
539 | 1131 | property int index | ||
540 | 1132 | property string filePath | ||
541 | 1133 | |||
542 | 1134 | width: childrenRect.width | ||
543 | 1135 | height: childrenRect.height | ||
544 | 1136 | |||
545 | 1137 | image: Image { | ||
546 | 1138 | id: avatarImage | ||
547 | 1139 | width: units.gu(8) | ||
548 | 1140 | height: units.gu(8) | ||
549 | 1141 | sourceSize.height: height | ||
550 | 1142 | sourceSize.width: width | ||
551 | 1143 | fillMode: Image.PreserveAspectCrop | ||
552 | 1144 | source: filePath | ||
553 | 1145 | asynchronous: true | ||
554 | 1146 | } | ||
555 | 1147 | MouseArea { | ||
556 | 1148 | anchors.fill: parent | ||
557 | 1149 | onPressAndHold: { | ||
558 | 1150 | mouse.accept = true | ||
559 | 1151 | Qt.inputMethod.hide() | ||
560 | 1152 | activeAttachmentIndex = index | ||
561 | 1153 | PopupUtils.open(attachmentPopover, parent) | ||
562 | 1154 | } | ||
563 | 1155 | } | ||
564 | 1156 | } | ||
565 | 1157 | } | ||
566 | 1158 | |||
567 | 1159 | Component { | ||
568 | 1160 | id: thumbnailContact | ||
569 | 1161 | Item { | ||
570 | 1162 | id: attachment | ||
571 | 1163 | |||
572 | 1164 | readonly property int contactsCount:vcardParser.contacts ? vcardParser.contacts.length : 0 | ||
573 | 1165 | property int index | ||
574 | 1166 | property string filePath | ||
575 | 1167 | property alias vcard: vcardParser | ||
576 | 1168 | property string contactDisplayName: { | ||
577 | 1169 | if (contactsCount > 0) { | ||
578 | 1170 | var contact = vcard.contacts[0] | ||
579 | 1171 | if (contact.displayLabel.label && (contact.displayLabel.label != "")) { | ||
580 | 1172 | return contact.displayLabel.label | ||
581 | 1173 | } else if (contact.name) { | ||
582 | 1174 | var contacFullName = contact.name.firstName | ||
583 | 1175 | if (contact.name.midleName) { | ||
584 | 1176 | contacFullName += " " + contact.name.midleName | ||
585 | 1177 | } | ||
586 | 1178 | if (contact.name.lastName) { | ||
587 | 1179 | contacFullName += " " + contact.name.lastName | ||
588 | 1180 | } | ||
589 | 1181 | return contacFullName | ||
590 | 1182 | } | ||
591 | 1183 | return i18n.tr("Unknown contact") | ||
592 | 1184 | } | ||
593 | 1185 | return "" | ||
594 | 1186 | } | ||
595 | 1187 | property string title: { | ||
596 | 1188 | var result = attachment.contactDisplayName | ||
597 | 1189 | if (attachment.contactsCount > 1) { | ||
598 | 1190 | return result + " (+%1)".arg(attachment.contactsCount-1) | ||
599 | 1191 | } else { | ||
600 | 1192 | return result | ||
601 | 1193 | } | ||
602 | 1194 | } | ||
603 | 1195 | |||
604 | 1196 | height: units.gu(6) | ||
605 | 1197 | width: textEntry.width | ||
606 | 1198 | |||
607 | 1199 | ContactAvatar { | ||
608 | 1200 | id: avatar | ||
609 | 1201 | |||
610 | 1202 | anchors { | ||
611 | 1203 | top: parent.top | ||
612 | 1204 | bottom: parent.bottom | ||
613 | 1205 | left: parent.left | ||
614 | 1206 | } | ||
615 | 1207 | contactElement: attachment.contactsCount === 1 ? attachment.vcard.contacts[0] : null | ||
616 | 1208 | fallbackAvatarUrl: attachment.contactsCount === 1 ? "image://theme/contact" : "image://theme/contact-group" | ||
617 | 1209 | fallbackDisplayName: attachment.contactsCount === 1 ? attachment.contactDisplayName : "" | ||
618 | 1210 | width: height | ||
619 | 1211 | } | ||
620 | 1212 | Label { | ||
621 | 1213 | id: label | ||
622 | 1214 | |||
623 | 1215 | anchors { | ||
624 | 1216 | left: avatar.right | ||
625 | 1217 | leftMargin: units.gu(1) | ||
626 | 1218 | top: avatar.top | ||
627 | 1219 | bottom: avatar.bottom | ||
628 | 1220 | right: parent.right | ||
629 | 1221 | rightMargin: units.gu(1) | ||
630 | 1222 | } | ||
631 | 1223 | |||
632 | 1224 | verticalAlignment: Text.AlignVCenter | ||
633 | 1225 | text: attachment.title | ||
634 | 1226 | elide: Text.ElideMiddle | ||
635 | 1227 | color: UbuntuColors.lightAubergine | ||
636 | 1228 | } | ||
637 | 1229 | MouseArea { | ||
638 | 1230 | anchors.fill: parent | ||
639 | 1231 | onPressAndHold: { | ||
640 | 1232 | mouse.accept = true | ||
641 | 1233 | Qt.inputMethod.hide() | ||
642 | 1234 | activeAttachmentIndex = index | ||
643 | 1235 | PopupUtils.open(attachmentPopover, parent) | ||
644 | 1236 | } | ||
645 | 1237 | } | ||
646 | 1238 | VCardParser { | ||
647 | 1239 | id: vcardParser | ||
648 | 1240 | |||
649 | 1241 | vCardUrl: attachment ? Qt.resolvedUrl(attachment.filePath) : "" | ||
650 | 1242 | } | ||
651 | 1243 | } | ||
652 | 1244 | } | ||
653 | 1245 | |||
654 | 1246 | Component { | ||
655 | 1247 | id: thumbnailUnknown | ||
656 | 1248 | |||
657 | 1249 | UbuntuShape { | ||
658 | 1250 | property int index | ||
659 | 1251 | property string filePath | ||
660 | 1252 | |||
661 | 1253 | width: units.gu(8) | ||
662 | 1254 | height: units.gu(8) | ||
663 | 1255 | |||
664 | 1256 | Icon { | ||
665 | 1257 | anchors.centerIn: parent | ||
666 | 1258 | width: units.gu(6) | ||
667 | 1259 | height: units.gu(6) | ||
668 | 1260 | name: "attachment" | ||
669 | 1261 | } | ||
670 | 1262 | MouseArea { | ||
671 | 1263 | anchors.fill: parent | ||
672 | 1264 | onPressAndHold: { | ||
673 | 1265 | mouse.accept = true | ||
674 | 1266 | Qt.inputMethod.hide() | ||
675 | 1267 | activeAttachmentIndex = index | ||
676 | 1268 | PopupUtils.open(attachmentPopover, parent) | ||
677 | 1269 | } | ||
678 | 1270 | } | ||
679 | 1271 | } | ||
680 | 1272 | } | ||
681 | 1273 | |||
682 | 1274 | Repeater { | ||
683 | 1275 | model: attachments | ||
684 | 1276 | delegate: Loader { | ||
685 | 1277 | height: units.gu(8) | ||
686 | 1278 | sourceComponent: { | ||
687 | 1279 | var contentType = getContentType(filePath) | ||
688 | 1280 | console.log(contentType) | ||
689 | 1281 | switch(contentType) { | ||
690 | 1282 | case ContentType.Contacts: | ||
691 | 1283 | return thumbnailContact | ||
692 | 1284 | case ContentType.Pictures: | ||
693 | 1285 | return thumbnailImage | ||
694 | 1286 | case ContentType.Unknown: | ||
695 | 1287 | return thumbnailUnknown | ||
696 | 1288 | default: | ||
697 | 1289 | console.log("unknown content Type") | ||
698 | 1290 | } | ||
699 | 1291 | } | ||
700 | 1292 | onStatusChanged: { | ||
701 | 1293 | if (status == Loader.Ready) { | ||
702 | 1294 | item.index = index | ||
703 | 1295 | item.filePath = filePath | ||
704 | 1296 | } | ||
705 | 1297 | } | ||
706 | 1298 | } | ||
707 | 1299 | } | ||
708 | 1300 | } | ||
709 | 1301 | |||
710 | 1302 | ListItem.ThinDivider { | ||
711 | 1303 | id: divider | ||
712 | 1304 | |||
713 | 1305 | anchors { | ||
714 | 1306 | left: parent.left | ||
715 | 1307 | right: parent.right | ||
716 | 1308 | top: attachmentThumbnails.bottom | ||
717 | 1309 | margins: units.gu(0.5) | ||
718 | 1310 | } | ||
719 | 1311 | visible: attachments.count > 0 | ||
720 | 1312 | } | ||
721 | 1313 | |||
722 | 1314 | TextArea { | ||
723 | 1315 | id: messageTextArea | ||
724 | 1316 | objectName: "messageTextArea" | ||
725 | 1317 | anchors { | ||
726 | 1318 | top: attachments.count == 0 ? textEntry.top : attachmentThumbnails.bottom | ||
727 | 1319 | left: parent.left | ||
728 | 1320 | right: parent.right | ||
729 | 1321 | } | ||
730 | 1322 | // this value is to avoid letter being cut off | ||
731 | 1323 | height: units.gu(4.3) | ||
732 | 1324 | style: LocalTextAreaStyle {} | ||
733 | 1325 | autoSize: true | ||
734 | 1326 | maximumLineCount: attachments.count == 0 ? 8 : 4 | ||
735 | 1327 | placeholderText: i18n.tr("Write a message...") | ||
736 | 1328 | focus: textEntry.focus | ||
737 | 1329 | font.family: "Ubuntu" | ||
738 | 1330 | font.pixelSize: FontUtils.sizeToPixels("medium") | ||
739 | 1331 | color: "#5d5d5d" | ||
740 | 1332 | text: messages.text | ||
741 | 1333 | } | ||
742 | 1334 | |||
743 | 1335 | /*InverseMouseArea { | ||
744 | 1336 | anchors.fill: parent | ||
745 | 1337 | visible: textEntry.activeFocus | ||
746 | 1338 | onClicked: { | ||
747 | 1339 | textEntry.focus = false; | ||
748 | 1340 | } | ||
749 | 1341 | }*/ | ||
750 | 1342 | Component.onCompleted: { | ||
751 | 1343 | // if page is active, it means this is not a bottom edge page | ||
752 | 1344 | if (messages.active && messages.keyboardFocus && participants.length != 0) { | ||
753 | 1345 | messageTextArea.forceActiveFocus() | ||
754 | 1346 | } | ||
755 | 1347 | } | ||
756 | 1348 | } | ||
757 | 1349 | |||
758 | 1350 | Icon { | ||
759 | 1351 | id: sendButton | ||
760 | 1352 | objectName: "sendButton" | ||
761 | 1353 | anchors.verticalCenter: textEntry.verticalCenter | ||
762 | 1354 | anchors.right: parent.right | ||
763 | 1355 | anchors.rightMargin: units.gu(2) | ||
764 | 1356 | color: "gray" | ||
765 | 1357 | source: Qt.resolvedUrl("./assets/send.svg") | ||
766 | 1358 | width: units.gu(3) | ||
767 | 1359 | height: units.gu(3) | ||
768 | 1360 | enabled: { | ||
769 | 1361 | if (participants.length > 0 || multiRecipient.recipientCount > 0 || multiRecipient.searchString !== "") { | ||
770 | 1362 | if (textEntry.text != "" || textEntry.inputMethodComposing || attachments.count > 0) { | ||
771 | 1363 | return true | ||
772 | 1364 | } | ||
773 | 1365 | } | ||
774 | 1366 | return false | ||
775 | 1367 | } | ||
776 | 1368 | |||
777 | 1369 | MouseArea { | ||
778 | 1370 | anchors.fill: parent | ||
779 | 1371 | anchors.margins: units.gu(-2) | ||
780 | 1372 | onClicked: { | ||
781 | 1373 | // make sure we flush everything we have prepared in the OSK preedit | ||
782 | 1374 | Qt.inputMethod.commit(); | ||
783 | 1375 | if (textEntry.text == "" && attachments.count == 0) { | ||
784 | 1376 | return | ||
785 | 1377 | } | ||
786 | 1378 | // refresh the recipient list | ||
787 | 1379 | multiRecipient.focus = false | ||
788 | 1380 | |||
789 | 1381 | if (messages.account && messages.accountId == "") { | ||
790 | 1382 | messages.accountId = messages.account.accountId | ||
791 | 1383 | messages.head.sections.selectedIndex = Qt.binding(getSelectedIndex) | ||
792 | 1384 | } | ||
793 | 1385 | |||
794 | 1386 | var newAttachments = [] | ||
795 | 1387 | for (var i = 0; i < attachments.count; i++) { | ||
796 | 1388 | var attachment = [] | ||
797 | 1389 | var item = attachments.get(i) | ||
798 | 1390 | // we dont include smil files. they will be auto generated | ||
799 | 1391 | if (item.contentType.toLowerCase() === "application/smil") { | ||
800 | 1392 | continue | ||
801 | 1393 | } | ||
802 | 1394 | attachment.push(item.name) | ||
803 | 1395 | attachment.push(item.contentType) | ||
804 | 1396 | attachment.push(item.filePath) | ||
805 | 1397 | newAttachments.push(attachment) | ||
806 | 1398 | } | ||
807 | 1399 | |||
808 | 1400 | var recipients = participantIds.length > 0 ? participantIds : | ||
809 | 1401 | multiRecipient.recipients | ||
810 | 1402 | // if sendMessage succeeds it means the message was either sent or | ||
811 | 1403 | // injected into the history service so the user can retry later | ||
812 | 1404 | if (sendMessage(textEntry.text, recipients, newAttachments)) { | ||
813 | 1405 | textEntry.text = "" | ||
814 | 1406 | attachments.clear() | ||
815 | 1407 | } | ||
816 | 1408 | if (eventModel.filter == null) { | ||
817 | 1409 | reloadFilters = !reloadFilters | ||
818 | 1410 | } | ||
819 | 1411 | } | ||
872 | 1412 | } | 1020 | } |
873 | 1413 | } | 1021 | } |
874 | 1414 | } | 1022 | } |
875 | 1415 | 1023 | ||
876 | === modified file 'src/qml/MessagesHeader.qml' | |||
877 | --- src/qml/MessagesHeader.qml 2015-08-04 01:06:06 +0000 | |||
878 | +++ src/qml/MessagesHeader.qml 2015-12-08 17:14:16 +0000 | |||
879 | @@ -18,7 +18,7 @@ | |||
880 | 18 | 18 | ||
881 | 19 | 19 | ||
882 | 20 | import QtQuick 2.2 | 20 | import QtQuick 2.2 |
884 | 21 | import Ubuntu.Components 1.1 | 21 | import Ubuntu.Components 1.3 |
885 | 22 | 22 | ||
886 | 23 | Item { | 23 | Item { |
887 | 24 | id: header | 24 | id: header |
888 | 25 | 25 | ||
889 | === added file 'src/qml/ThumbnailContact.qml' | |||
890 | --- src/qml/ThumbnailContact.qml 1970-01-01 00:00:00 +0000 | |||
891 | +++ src/qml/ThumbnailContact.qml 2015-12-08 17:14:16 +0000 | |||
892 | @@ -0,0 +1,106 @@ | |||
893 | 1 | /* | ||
894 | 2 | * Copyright 2012-2015 Canonical Ltd. | ||
895 | 3 | * | ||
896 | 4 | * This file is part of messaging-app. | ||
897 | 5 | * | ||
898 | 6 | * messaging-app is free software; you can redistribute it and/or modify | ||
899 | 7 | * it under the terms of the GNU General Public License as published by | ||
900 | 8 | * the Free Software Foundation; version 3. | ||
901 | 9 | * | ||
902 | 10 | * messaging-app is distributed in the hope that it will be useful, | ||
903 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
904 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
905 | 13 | * GNU General Public License for more details. | ||
906 | 14 | * | ||
907 | 15 | * You should have received a copy of the GNU General Public License | ||
908 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
909 | 17 | */ | ||
910 | 18 | |||
911 | 19 | import QtQuick 2.0 | ||
912 | 20 | import Ubuntu.Components 1.3 | ||
913 | 21 | import Ubuntu.Contacts 0.1 | ||
914 | 22 | |||
915 | 23 | Item { | ||
916 | 24 | id: attachment | ||
917 | 25 | |||
918 | 26 | readonly property int contactsCount:vcardParser.contacts ? vcardParser.contacts.length : 0 | ||
919 | 27 | property int index | ||
920 | 28 | property string filePath | ||
921 | 29 | property alias vcard: vcardParser | ||
922 | 30 | property string contactDisplayName: { | ||
923 | 31 | if (contactsCount > 0) { | ||
924 | 32 | var contact = vcard.contacts[0] | ||
925 | 33 | if (contact.displayLabel.label && (contact.displayLabel.label != "")) { | ||
926 | 34 | return contact.displayLabel.label | ||
927 | 35 | } else if (contact.name) { | ||
928 | 36 | var contacFullName = contact.name.firstName | ||
929 | 37 | if (contact.name.midleName) { | ||
930 | 38 | contacFullName += " " + contact.name.midleName | ||
931 | 39 | } | ||
932 | 40 | if (contact.name.lastName) { | ||
933 | 41 | contacFullName += " " + contact.name.lastName | ||
934 | 42 | } | ||
935 | 43 | return contacFullName | ||
936 | 44 | } | ||
937 | 45 | return i18n.tr("Unknown contact") | ||
938 | 46 | } | ||
939 | 47 | return "" | ||
940 | 48 | } | ||
941 | 49 | property string title: { | ||
942 | 50 | var result = attachment.contactDisplayName | ||
943 | 51 | if (attachment.contactsCount > 1) { | ||
944 | 52 | return result + " (+%1)".arg(attachment.contactsCount-1) | ||
945 | 53 | } else { | ||
946 | 54 | return result | ||
947 | 55 | } | ||
948 | 56 | } | ||
949 | 57 | |||
950 | 58 | signal pressAndHold() | ||
951 | 59 | |||
952 | 60 | height: units.gu(6) | ||
953 | 61 | width: textEntry.width | ||
954 | 62 | |||
955 | 63 | ContactAvatar { | ||
956 | 64 | id: avatar | ||
957 | 65 | |||
958 | 66 | anchors { | ||
959 | 67 | top: parent.top | ||
960 | 68 | bottom: parent.bottom | ||
961 | 69 | left: parent.left | ||
962 | 70 | } | ||
963 | 71 | contactElement: attachment.contactsCount === 1 ? attachment.vcard.contacts[0] : null | ||
964 | 72 | fallbackAvatarUrl: attachment.contactsCount === 1 ? "image://theme/contact" : "image://theme/contact-group" | ||
965 | 73 | fallbackDisplayName: attachment.contactsCount === 1 ? attachment.contactDisplayName : "" | ||
966 | 74 | width: height | ||
967 | 75 | } | ||
968 | 76 | Label { | ||
969 | 77 | id: label | ||
970 | 78 | |||
971 | 79 | anchors { | ||
972 | 80 | left: avatar.right | ||
973 | 81 | leftMargin: units.gu(1) | ||
974 | 82 | top: avatar.top | ||
975 | 83 | bottom: avatar.bottom | ||
976 | 84 | right: parent.right | ||
977 | 85 | rightMargin: units.gu(1) | ||
978 | 86 | } | ||
979 | 87 | |||
980 | 88 | verticalAlignment: Text.AlignVCenter | ||
981 | 89 | text: attachment.title | ||
982 | 90 | elide: Text.ElideMiddle | ||
983 | 91 | color: UbuntuColors.lightAubergine | ||
984 | 92 | } | ||
985 | 93 | MouseArea { | ||
986 | 94 | anchors.fill: parent | ||
987 | 95 | onPressAndHold: { | ||
988 | 96 | mouse.accept = true | ||
989 | 97 | attachment.pressAndHold() | ||
990 | 98 | } | ||
991 | 99 | } | ||
992 | 100 | VCardParser { | ||
993 | 101 | id: vcardParser | ||
994 | 102 | |||
995 | 103 | vCardUrl: attachment ? Qt.resolvedUrl(attachment.filePath) : "" | ||
996 | 104 | } | ||
997 | 105 | } | ||
998 | 106 | |||
999 | 0 | 107 | ||
1000 | === added file 'src/qml/ThumbnailImage.qml' | |||
1001 | --- src/qml/ThumbnailImage.qml 1970-01-01 00:00:00 +0000 | |||
1002 | +++ src/qml/ThumbnailImage.qml 2015-12-08 17:14:16 +0000 | |||
1003 | @@ -0,0 +1,49 @@ | |||
1004 | 1 | /* | ||
1005 | 2 | * Copyright 2012-2015 Canonical Ltd. | ||
1006 | 3 | * | ||
1007 | 4 | * This file is part of messaging-app. | ||
1008 | 5 | * | ||
1009 | 6 | * messaging-app is free software; you can redistribute it and/or modify | ||
1010 | 7 | * it under the terms of the GNU General Public License as published by | ||
1011 | 8 | * the Free Software Foundation; version 3. | ||
1012 | 9 | * | ||
1013 | 10 | * messaging-app is distributed in the hope that it will be useful, | ||
1014 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1015 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1016 | 13 | * GNU General Public License for more details. | ||
1017 | 14 | * | ||
1018 | 15 | * You should have received a copy of the GNU General Public License | ||
1019 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1020 | 17 | */ | ||
1021 | 18 | |||
1022 | 19 | import QtQuick 2.0 | ||
1023 | 20 | import Ubuntu.Components 1.3 | ||
1024 | 21 | |||
1025 | 22 | UbuntuShape { | ||
1026 | 23 | id: thumbnail | ||
1027 | 24 | property int index | ||
1028 | 25 | property string filePath | ||
1029 | 26 | |||
1030 | 27 | signal pressAndHold() | ||
1031 | 28 | |||
1032 | 29 | width: childrenRect.width | ||
1033 | 30 | height: childrenRect.height | ||
1034 | 31 | |||
1035 | 32 | image: Image { | ||
1036 | 33 | id: avatarImage | ||
1037 | 34 | width: units.gu(8) | ||
1038 | 35 | height: units.gu(8) | ||
1039 | 36 | sourceSize.height: height | ||
1040 | 37 | sourceSize.width: width | ||
1041 | 38 | fillMode: Image.PreserveAspectCrop | ||
1042 | 39 | source: filePath | ||
1043 | 40 | asynchronous: true | ||
1044 | 41 | } | ||
1045 | 42 | MouseArea { | ||
1046 | 43 | anchors.fill: parent | ||
1047 | 44 | onPressAndHold: { | ||
1048 | 45 | mouse.accept = true | ||
1049 | 46 | thumbnail.pressAndHold() | ||
1050 | 47 | } | ||
1051 | 48 | } | ||
1052 | 49 | } | ||
1053 | 0 | 50 | ||
1054 | === added file 'src/qml/ThumbnailUnknown.qml' | |||
1055 | --- src/qml/ThumbnailUnknown.qml 1970-01-01 00:00:00 +0000 | |||
1056 | +++ src/qml/ThumbnailUnknown.qml 2015-12-08 17:14:16 +0000 | |||
1057 | @@ -0,0 +1,45 @@ | |||
1058 | 1 | /* | ||
1059 | 2 | * Copyright 2012-2015 Canonical Ltd. | ||
1060 | 3 | * | ||
1061 | 4 | * This file is part of messaging-app. | ||
1062 | 5 | * | ||
1063 | 6 | * messaging-app is free software; you can redistribute it and/or modify | ||
1064 | 7 | * it under the terms of the GNU General Public License as published by | ||
1065 | 8 | * the Free Software Foundation; version 3. | ||
1066 | 9 | * | ||
1067 | 10 | * messaging-app is distributed in the hope that it will be useful, | ||
1068 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1069 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1070 | 13 | * GNU General Public License for more details. | ||
1071 | 14 | * | ||
1072 | 15 | * You should have received a copy of the GNU General Public License | ||
1073 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1074 | 17 | */ | ||
1075 | 18 | |||
1076 | 19 | import QtQuick 2.0 | ||
1077 | 20 | import Ubuntu.Components 1.3 | ||
1078 | 21 | |||
1079 | 22 | UbuntuShape { | ||
1080 | 23 | id: thumbnail | ||
1081 | 24 | property int index | ||
1082 | 25 | property string filePath | ||
1083 | 26 | |||
1084 | 27 | signal pressAndHold() | ||
1085 | 28 | |||
1086 | 29 | width: units.gu(8) | ||
1087 | 30 | height: units.gu(8) | ||
1088 | 31 | |||
1089 | 32 | Icon { | ||
1090 | 33 | anchors.centerIn: parent | ||
1091 | 34 | width: units.gu(6) | ||
1092 | 35 | height: units.gu(6) | ||
1093 | 36 | name: "attachment" | ||
1094 | 37 | } | ||
1095 | 38 | MouseArea { | ||
1096 | 39 | anchors.fill: parent | ||
1097 | 40 | onPressAndHold: { | ||
1098 | 41 | mouse.accept = true | ||
1099 | 42 | thumbnail.pressAndHold() | ||
1100 | 43 | } | ||
1101 | 44 | } | ||
1102 | 45 | } | ||
1103 | 0 | 46 | ||
1104 | === added file 'src/qml/TransparentButton.qml' | |||
1105 | --- src/qml/TransparentButton.qml 1970-01-01 00:00:00 +0000 | |||
1106 | +++ src/qml/TransparentButton.qml 2015-12-08 17:14:16 +0000 | |||
1107 | @@ -0,0 +1,86 @@ | |||
1108 | 1 | /* | ||
1109 | 2 | * Copyright 2015 Canonical Ltd. | ||
1110 | 3 | * | ||
1111 | 4 | * This file is part of messaging-app. | ||
1112 | 5 | * | ||
1113 | 6 | * messaging-app is free software; you can redistribute it and/or modify | ||
1114 | 7 | * it under the terms of the GNU General Public License as published by | ||
1115 | 8 | * the Free Software Foundation; version 3. | ||
1116 | 9 | * | ||
1117 | 10 | * messaging-app is distributed in the hope that it will be useful, | ||
1118 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1119 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1120 | 13 | * GNU General Public License for more details. | ||
1121 | 14 | * | ||
1122 | 15 | * You should have received a copy of the GNU General Public License | ||
1123 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1124 | 17 | */ | ||
1125 | 18 | |||
1126 | 19 | import QtQuick 2.0 | ||
1127 | 20 | import Ubuntu.Components 1.3 | ||
1128 | 21 | |||
1129 | 22 | Item { | ||
1130 | 23 | id: button | ||
1131 | 24 | |||
1132 | 25 | width: icon.width | ||
1133 | 26 | height: icon.height + label.height + spacing | ||
1134 | 27 | |||
1135 | 28 | property alias iconName: icon.name | ||
1136 | 29 | property alias iconSource: icon.source | ||
1137 | 30 | property alias iconColor: icon.color | ||
1138 | 31 | property int iconSize: units.gu(2) | ||
1139 | 32 | property alias iconRotation: icon.rotation | ||
1140 | 33 | property alias text: label.text | ||
1141 | 34 | property alias textSize: label.font.pixelSize | ||
1142 | 35 | property int spacing: 0 | ||
1143 | 36 | |||
1144 | 37 | signal clicked() | ||
1145 | 38 | signal pressed() | ||
1146 | 39 | signal released() | ||
1147 | 40 | |||
1148 | 41 | Icon { | ||
1149 | 42 | id: icon | ||
1150 | 43 | |||
1151 | 44 | anchors { | ||
1152 | 45 | left: parent.left | ||
1153 | 46 | right: parent.right | ||
1154 | 47 | top: parent.top | ||
1155 | 48 | } | ||
1156 | 49 | |||
1157 | 50 | height: iconSize | ||
1158 | 51 | width: iconSize | ||
1159 | 52 | color: "gray" | ||
1160 | 53 | Behavior on rotation { | ||
1161 | 54 | UbuntuNumberAnimation { } | ||
1162 | 55 | } | ||
1163 | 56 | } | ||
1164 | 57 | |||
1165 | 58 | MouseArea { | ||
1166 | 59 | anchors { | ||
1167 | 60 | fill: parent | ||
1168 | 61 | margins: units.gu(-2) | ||
1169 | 62 | } | ||
1170 | 63 | onClicked: { | ||
1171 | 64 | mouse.accepted = true | ||
1172 | 65 | button.clicked() | ||
1173 | 66 | } | ||
1174 | 67 | |||
1175 | 68 | onPressed: button.pressed() | ||
1176 | 69 | onReleased: button.released() | ||
1177 | 70 | } | ||
1178 | 71 | |||
1179 | 72 | Text { | ||
1180 | 73 | id: label | ||
1181 | 74 | color: "gray" | ||
1182 | 75 | height: text !== "" ? paintedHeight : 0 | ||
1183 | 76 | anchors { | ||
1184 | 77 | left: parent.left | ||
1185 | 78 | right: parent.right | ||
1186 | 79 | bottom: parent.bottom | ||
1187 | 80 | } | ||
1188 | 81 | horizontalAlignment: Text.AlignHCenter | ||
1189 | 82 | verticalAlignment: Text.AlignBottom | ||
1190 | 83 | font.family: "Ubuntu" | ||
1191 | 84 | font.pixelSize: FontUtils.sizeToPixels("small") | ||
1192 | 85 | } | ||
1193 | 86 | } |
FAILED: Continuous integration, rev:443 jenkins. qa.ubuntu. com/job/ messaging- app-ci/ 734/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 5305/console jenkins. qa.ubuntu. com/job/ messaging- app-vivid- i386-ci/ 247/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 5325/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/messaging- app-ci/ 734/rebuild
http://