Merge lp:~artmello/messaging-app/messaging-app-video_attachment into lp:messaging-app
- messaging-app-video_attachment
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 488 |
Proposed branch: | lp:~artmello/messaging-app/messaging-app-video_attachment |
Merge into: | lp:messaging-app |
Prerequisite: | lp:~boiko/messaging-app/more_attachment_types |
Diff against target: |
1483 lines (+1035/-123) 20 files modified
debian/control (+2/-0) src/CMakeLists.txt (+2/-0) src/fileoperations.cpp (+48/-0) src/fileoperations.h (+39/-0) src/messagingapplication.cpp (+28/-1) src/messagingapplication.h (+7/-1) src/qml/AttachmentPanel.qml (+2/-3) src/qml/ComposeBar.qml (+2/-0) src/qml/MMS/MMSImage.qml (+1/-0) src/qml/MMS/MMSVideo.qml (+60/-44) src/qml/MMS/PreviewerImage.qml (+183/-8) src/qml/MMS/PreviewerVideo.qml (+124/-33) src/qml/MMSDelegate.qml (+6/-7) src/qml/ThumbnailVideo.qml (+76/-0) src/qml/messaging-app.qml (+3/-1) tests/qml/CMakeLists.txt (+34/-25) tests/qml/tst_MMSDelegate.qml (+167/-0) tests/qml/tst_PreviewerImage.qml (+103/-0) tests/qml/tst_PreviewerVideo.qml (+87/-0) tests/qml/tst_QmlTests.cpp (+61/-0) |
To merge this branch: | bzr merge lp:~artmello/messaging-app/messaging-app-video_attachment |
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+278476@code.launchpad.net |
Commit message
Add video attachment delegates
Description of the change
Add video attachment delegates
- 476. By Arthur Mello
-
Update headers
PS Jenkins bot (ps-jenkins) wrote : | # |
- 477. By Arthur Mello
-
Add initial qml test
- 478. By Arthur Mello
-
Change on MMSDelegate to look for participants from messageData
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:477
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:478
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Tiago Salem Herrmann (tiagosh) : | # |
- 479. By Arthur Mello
-
Add QML tests for MMSDelegate
- 480. By Arthur Mello
-
Add PreviewerImage QML tests
- 481. By Arthur Mello
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:481
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 482. By Arthur Mello
-
Add TODO message for FileOperations
Remove mimetype check used for testing
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:482
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 483. By Arthur Mello
-
Change QML test structure so we could include messaingapp.private
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:483
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 484. By Arthur Mello
-
Fix build
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:484
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 485. By Arthur Mello
-
Add PreviewerVideo qml tests
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:485
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 486. By Arthur Mello
-
Merge with parent
- 487. By Arthur Mello
-
Add build dep
- 488. By Arthur Mello
-
Add build dep
- 489. By Arthur Mello
-
Fix QML test
- 490. By Arthur Mello
-
Fix QML tests
- 491. By Arthur Mello
-
Add sample file
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:486
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:491
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 492. By Arthur Mello
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:492
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 493. By Arthur Mello
-
Add Video Thumbnail
- 494. By Arthur Mello
-
Fix typo
- 495. By Arthur Mello
-
Show ActivityIndicator while loading thumbnail
Fix thumbnail path
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:493
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:495
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 496. By Arthur Mello
-
Use VideoOutput instead of Video QML component
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:496
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 497. By Arthur Mello
-
Merge with parent branch
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:497
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 498. By Arthur Mello
-
Merge with parent branch
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:498
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2015-09-11 14:25:57 +0000 | |||
3 | +++ debian/control 2015-12-08 18:33:04 +0000 | |||
4 | @@ -21,8 +21,10 @@ | |||
5 | 21 | qtdeclarative5-ubuntu-telephony0.1 | qtdeclarative5-ubuntu-telephony-plugin, | 21 | qtdeclarative5-ubuntu-telephony0.1 | qtdeclarative5-ubuntu-telephony-plugin, |
6 | 22 | qtdeclarative5-ubuntu-content1, | 22 | qtdeclarative5-ubuntu-content1, |
7 | 23 | qtdeclarative5-ubuntu-addressbook0.1, | 23 | qtdeclarative5-ubuntu-addressbook0.1, |
8 | 24 | qtdeclarative5-ubuntu-thumbnailer0.1, | ||
9 | 24 | qtdeclarative5-qtcontacts-plugin, | 25 | qtdeclarative5-qtcontacts-plugin, |
10 | 25 | qml-module-qt-labs-settings, | 26 | qml-module-qt-labs-settings, |
11 | 27 | qml-module-qtmultimedia, | ||
12 | 26 | qtpim5-dev, | 28 | qtpim5-dev, |
13 | 27 | xvfb, | 29 | xvfb, |
14 | 28 | Standards-Version: 3.9.4 | 30 | Standards-Version: 3.9.4 |
15 | 29 | 31 | ||
16 | === modified file 'src/CMakeLists.txt' | |||
17 | --- src/CMakeLists.txt 2015-02-24 13:33:31 +0000 | |||
18 | +++ src/CMakeLists.txt 2015-12-08 18:33:04 +0000 | |||
19 | @@ -1,10 +1,12 @@ | |||
20 | 1 | set(MESSAGING_APP messaging-app) | 1 | set(MESSAGING_APP messaging-app) |
21 | 2 | 2 | ||
22 | 3 | set(messaging_app_HDRS | 3 | set(messaging_app_HDRS |
23 | 4 | fileoperations.h | ||
24 | 4 | messagingapplication.h | 5 | messagingapplication.h |
25 | 5 | ) | 6 | ) |
26 | 6 | 7 | ||
27 | 7 | set(messaging_app_SRCS | 8 | set(messaging_app_SRCS |
28 | 9 | fileoperations.cpp | ||
29 | 8 | messagingapplication.cpp | 10 | messagingapplication.cpp |
30 | 9 | main.cpp | 11 | main.cpp |
31 | 10 | ) | 12 | ) |
32 | 11 | 13 | ||
33 | === added file 'src/fileoperations.cpp' | |||
34 | --- src/fileoperations.cpp 1970-01-01 00:00:00 +0000 | |||
35 | +++ src/fileoperations.cpp 2015-12-08 18:33:04 +0000 | |||
36 | @@ -0,0 +1,48 @@ | |||
37 | 1 | /* | ||
38 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
39 | 3 | * | ||
40 | 4 | * Authors: | ||
41 | 5 | * Arthur Mello <arthur.mello@canonical.com> | ||
42 | 6 | * | ||
43 | 7 | * This file is part of messaging-app. | ||
44 | 8 | * | ||
45 | 9 | * messaging-app is free software; you can redistribute it and/or modify | ||
46 | 10 | * it under the terms of the GNU General Public License as published by | ||
47 | 11 | * the Free Software Foundation; version 3. | ||
48 | 12 | * | ||
49 | 13 | * messaging-app is distributed in the hope that it will be useful, | ||
50 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
51 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
52 | 16 | * GNU General Public License for more details. | ||
53 | 17 | * | ||
54 | 18 | * You should have received a copy of the GNU General Public License | ||
55 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
56 | 20 | */ | ||
57 | 21 | |||
58 | 22 | #include "fileoperations.h" | ||
59 | 23 | |||
60 | 24 | #include <QDir> | ||
61 | 25 | #include <QFile> | ||
62 | 26 | #include <QTemporaryFile> | ||
63 | 27 | |||
64 | 28 | FileOperations::FileOperations(QObject *parent) | ||
65 | 29 | : QObject(parent) | ||
66 | 30 | { | ||
67 | 31 | } | ||
68 | 32 | |||
69 | 33 | FileOperations::~FileOperations() | ||
70 | 34 | { | ||
71 | 35 | } | ||
72 | 36 | |||
73 | 37 | QString FileOperations::getTemporaryFile(const QString &fileExtension) const | ||
74 | 38 | { | ||
75 | 39 | //TODO remove once lp:1420728 is fixed | ||
76 | 40 | QTemporaryFile tmp(QDir::tempPath() + "/tmpXXXXXX" + fileExtension); | ||
77 | 41 | tmp.open(); | ||
78 | 42 | return tmp.fileName(); | ||
79 | 43 | } | ||
80 | 44 | |||
81 | 45 | bool FileOperations::link(const QString &from, const QString &to) | ||
82 | 46 | { | ||
83 | 47 | return QFile::link(from, to); | ||
84 | 48 | } | ||
85 | 0 | 49 | ||
86 | === added file 'src/fileoperations.h' | |||
87 | --- src/fileoperations.h 1970-01-01 00:00:00 +0000 | |||
88 | +++ src/fileoperations.h 2015-12-08 18:33:04 +0000 | |||
89 | @@ -0,0 +1,39 @@ | |||
90 | 1 | /* | ||
91 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
92 | 3 | * | ||
93 | 4 | * Authors: | ||
94 | 5 | * Arthur Mello <arthur.mello@canonical.com> | ||
95 | 6 | * | ||
96 | 7 | * This file is part of messaging-app. | ||
97 | 8 | * | ||
98 | 9 | * messaging-app is free software; you can redistribute it and/or modify | ||
99 | 10 | * it under the terms of the GNU General Public License as published by | ||
100 | 11 | * the Free Software Foundation; version 3. | ||
101 | 12 | * | ||
102 | 13 | * messaging-app is distributed in the hope that it will be useful, | ||
103 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
104 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
105 | 16 | * GNU General Public License for more details. | ||
106 | 17 | * | ||
107 | 18 | * You should have received a copy of the GNU General Public License | ||
108 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
109 | 20 | */ | ||
110 | 21 | |||
111 | 22 | #ifndef FILEOPERATIONS_H | ||
112 | 23 | #define FILEOPERATIONS_H | ||
113 | 24 | |||
114 | 25 | #include <QObject> | ||
115 | 26 | |||
116 | 27 | class FileOperations : public QObject | ||
117 | 28 | { | ||
118 | 29 | Q_OBJECT | ||
119 | 30 | |||
120 | 31 | public: | ||
121 | 32 | FileOperations(QObject *parent = 0); | ||
122 | 33 | ~FileOperations(); | ||
123 | 34 | |||
124 | 35 | Q_INVOKABLE QString getTemporaryFile(const QString &fileExtension) const; | ||
125 | 36 | Q_INVOKABLE bool link(const QString &from, const QString &to); | ||
126 | 37 | }; | ||
127 | 38 | |||
128 | 39 | #endif // FILEOPERATIONS_H | ||
129 | 0 | 40 | ||
130 | === modified file 'src/messagingapplication.cpp' | |||
131 | --- src/messagingapplication.cpp 2015-11-23 19:51:16 +0000 | |||
132 | +++ src/messagingapplication.cpp 2015-12-08 18:33:04 +0000 | |||
133 | @@ -1,5 +1,5 @@ | |||
134 | 1 | /* | 1 | /* |
136 | 2 | * Copyright (C) 2012 Canonical, Ltd. | 2 | * Copyright (C) 2012-2015 Canonical, Ltd. |
137 | 3 | * | 3 | * |
138 | 4 | * This file is part of messaging-app. | 4 | * This file is part of messaging-app. |
139 | 5 | * | 5 | * |
140 | @@ -17,6 +17,7 @@ | |||
141 | 17 | */ | 17 | */ |
142 | 18 | 18 | ||
143 | 19 | #include "messagingapplication.h" | 19 | #include "messagingapplication.h" |
144 | 20 | #include "fileoperations.h" | ||
145 | 20 | 21 | ||
146 | 21 | #include <libnotify/notify.h> | 22 | #include <libnotify/notify.h> |
147 | 22 | 23 | ||
148 | @@ -65,12 +66,24 @@ | |||
149 | 65 | } | 66 | } |
150 | 66 | } | 67 | } |
151 | 67 | 68 | ||
152 | 69 | static QObject* FileOperations_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) | ||
153 | 70 | { | ||
154 | 71 | Q_UNUSED(engine); | ||
155 | 72 | Q_UNUSED(scriptEngine); | ||
156 | 73 | return new FileOperations(); | ||
157 | 74 | } | ||
158 | 75 | |||
159 | 68 | MessagingApplication::MessagingApplication(int &argc, char **argv) | 76 | MessagingApplication::MessagingApplication(int &argc, char **argv) |
160 | 69 | : QGuiApplication(argc, argv), m_view(0), m_applicationIsReady(false) | 77 | : QGuiApplication(argc, argv), m_view(0), m_applicationIsReady(false) |
161 | 70 | { | 78 | { |
162 | 71 | setApplicationName("MessagingApp"); | 79 | setApplicationName("MessagingApp"); |
163 | 72 | } | 80 | } |
164 | 73 | 81 | ||
165 | 82 | bool MessagingApplication::fullscreen() const | ||
166 | 83 | { | ||
167 | 84 | return m_view->windowState() == Qt::WindowFullScreen; | ||
168 | 85 | } | ||
169 | 86 | |||
170 | 74 | bool MessagingApplication::setup() | 87 | bool MessagingApplication::setup() |
171 | 75 | { | 88 | { |
172 | 76 | installIconPath(); | 89 | installIconPath(); |
173 | @@ -133,6 +146,9 @@ | |||
174 | 133 | } | 146 | } |
175 | 134 | } | 147 | } |
176 | 135 | 148 | ||
177 | 149 | const char* uri = "messagingapp.private"; | ||
178 | 150 | qmlRegisterSingletonType<FileOperations>(uri, 0, 1, "FileOperations", FileOperations_singleton_factory); | ||
179 | 151 | |||
180 | 136 | m_view = new QQuickView(); | 152 | m_view = new QQuickView(); |
181 | 137 | QObject::connect(m_view, SIGNAL(statusChanged(QQuickView::Status)), this, SLOT(onViewStatusChanged(QQuickView::Status))); | 153 | QObject::connect(m_view, SIGNAL(statusChanged(QQuickView::Status)), this, SLOT(onViewStatusChanged(QQuickView::Status))); |
182 | 138 | QObject::connect(m_view->engine(), SIGNAL(quit()), SLOT(quit())); | 154 | QObject::connect(m_view->engine(), SIGNAL(quit()), SLOT(quit())); |
183 | @@ -176,6 +192,17 @@ | |||
184 | 176 | } | 192 | } |
185 | 177 | } | 193 | } |
186 | 178 | 194 | ||
187 | 195 | void MessagingApplication::setFullscreen(bool fullscreen) | ||
188 | 196 | { | ||
189 | 197 | if (fullscreen) { | ||
190 | 198 | m_view->setWindowState(Qt::WindowFullScreen); | ||
191 | 199 | } else { | ||
192 | 200 | m_view->setWindowState(Qt::WindowNoState); | ||
193 | 201 | } | ||
194 | 202 | |||
195 | 203 | Q_EMIT fullscreenChanged(); | ||
196 | 204 | } | ||
197 | 205 | |||
198 | 179 | void MessagingApplication::onViewStatusChanged(QQuickView::Status status) | 206 | void MessagingApplication::onViewStatusChanged(QQuickView::Status status) |
199 | 180 | { | 207 | { |
200 | 181 | if (status != QQuickView::Ready) { | 208 | if (status != QQuickView::Ready) { |
201 | 182 | 209 | ||
202 | === modified file 'src/messagingapplication.h' | |||
203 | --- src/messagingapplication.h 2015-11-18 16:36:51 +0000 | |||
204 | +++ src/messagingapplication.h 2015-12-08 18:33:04 +0000 | |||
205 | @@ -1,5 +1,5 @@ | |||
206 | 1 | /* | 1 | /* |
208 | 2 | * Copyright (C) 2012-2013 Canonical, Ltd. | 2 | * Copyright (C) 2012-2015 Canonical, Ltd. |
209 | 3 | * | 3 | * |
210 | 4 | * This file is part of messaging-app. | 4 | * This file is part of messaging-app. |
211 | 5 | * | 5 | * |
212 | @@ -26,13 +26,18 @@ | |||
213 | 26 | class MessagingApplication : public QGuiApplication | 26 | class MessagingApplication : public QGuiApplication |
214 | 27 | { | 27 | { |
215 | 28 | Q_OBJECT | 28 | Q_OBJECT |
216 | 29 | Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged) | ||
217 | 29 | 30 | ||
218 | 30 | public: | 31 | public: |
219 | 31 | MessagingApplication(int &argc, char **argv); | 32 | MessagingApplication(int &argc, char **argv); |
220 | 32 | virtual ~MessagingApplication(); | 33 | virtual ~MessagingApplication(); |
221 | 33 | 34 | ||
222 | 35 | bool fullscreen() const; | ||
223 | 34 | bool setup(); | 36 | bool setup(); |
224 | 35 | 37 | ||
225 | 38 | Q_SIGNALS: | ||
226 | 39 | void fullscreenChanged(); | ||
227 | 40 | |||
228 | 36 | public Q_SLOTS: | 41 | public Q_SLOTS: |
229 | 37 | void activateWindow(); | 42 | void activateWindow(); |
230 | 38 | void parseArgument(const QString &arg); | 43 | void parseArgument(const QString &arg); |
231 | @@ -41,6 +46,7 @@ | |||
232 | 41 | void showNotificationMessage(const QString &message, const QString &icon = QString()); | 46 | void showNotificationMessage(const QString &message, const QString &icon = QString()); |
233 | 42 | 47 | ||
234 | 43 | private Q_SLOTS: | 48 | private Q_SLOTS: |
235 | 49 | void setFullscreen(bool fullscreen); | ||
236 | 44 | void onViewStatusChanged(QQuickView::Status status); | 50 | void onViewStatusChanged(QQuickView::Status status); |
237 | 45 | void onApplicationReady(); | 51 | void onApplicationReady(); |
238 | 46 | 52 | ||
239 | 47 | 53 | ||
240 | === modified file 'src/qml/AttachmentPanel.qml' | |||
241 | --- src/qml/AttachmentPanel.qml 2015-12-08 18:33:04 +0000 | |||
242 | +++ src/qml/AttachmentPanel.qml 2015-12-08 18:33:04 +0000 | |||
243 | @@ -102,8 +102,7 @@ | |||
244 | 102 | } | 102 | } |
245 | 103 | } | 103 | } |
246 | 104 | 104 | ||
249 | 105 | // FIXME: re-enable that once we have proper delegates | 105 | TransparentButton { |
248 | 106 | /*TransparentButton { | ||
250 | 107 | id: videoButton | 106 | id: videoButton |
251 | 108 | objectName: "videoButton" | 107 | objectName: "videoButton" |
252 | 109 | iconName: "stock_video" | 108 | iconName: "stock_video" |
253 | @@ -114,7 +113,7 @@ | |||
254 | 114 | onClicked: { | 113 | onClicked: { |
255 | 115 | contentImporter.requestVideo() | 114 | contentImporter.requestVideo() |
256 | 116 | } | 115 | } |
258 | 117 | }*/ | 116 | } |
259 | 118 | 117 | ||
260 | 119 | // FIXME: enable generic file sharing if we ever support it | 118 | // FIXME: enable generic file sharing if we ever support it |
261 | 120 | /*TransparentButton { | 119 | /*TransparentButton { |
262 | 121 | 120 | ||
263 | === modified file 'src/qml/ComposeBar.qml' | |||
264 | --- src/qml/ComposeBar.qml 2015-12-08 18:33:04 +0000 | |||
265 | +++ src/qml/ComposeBar.qml 2015-12-08 18:33:04 +0000 | |||
266 | @@ -204,6 +204,8 @@ | |||
267 | 204 | return Qt.resolvedUrl("ThumbnailContact.qml") | 204 | return Qt.resolvedUrl("ThumbnailContact.qml") |
268 | 205 | case ContentType.Pictures: | 205 | case ContentType.Pictures: |
269 | 206 | return Qt.resolvedUrl("ThumbnailImage.qml") | 206 | return Qt.resolvedUrl("ThumbnailImage.qml") |
270 | 207 | case ContentType.Videos: | ||
271 | 208 | return Qt.resolvedUrl("ThumbnailVideo.qml") | ||
272 | 207 | case ContentType.Unknown: | 209 | case ContentType.Unknown: |
273 | 208 | return Qt.resolvedUrl("ThumbnailUnknown.qml") | 210 | return Qt.resolvedUrl("ThumbnailUnknown.qml") |
274 | 209 | default: | 211 | default: |
275 | 210 | 212 | ||
276 | === modified file 'src/qml/MMS/MMSImage.qml' | |||
277 | --- src/qml/MMS/MMSImage.qml 2015-09-14 13:51:27 +0000 | |||
278 | +++ src/qml/MMS/MMSImage.qml 2015-12-08 18:33:04 +0000 | |||
279 | @@ -34,6 +34,7 @@ | |||
280 | 34 | 34 | ||
281 | 35 | image: Image { | 35 | image: Image { |
282 | 36 | id: imageAttachment | 36 | id: imageAttachment |
283 | 37 | objectName: "imageAttachment" | ||
284 | 37 | 38 | ||
285 | 38 | fillMode: Image.PreserveAspectCrop | 39 | fillMode: Image.PreserveAspectCrop |
286 | 39 | smooth: true | 40 | smooth: true |
287 | 40 | 41 | ||
288 | === modified file 'src/qml/MMS/MMSVideo.qml' | |||
289 | --- src/qml/MMS/MMSVideo.qml 2015-09-14 13:51:27 +0000 | |||
290 | +++ src/qml/MMS/MMSVideo.qml 2015-12-08 18:33:04 +0000 | |||
291 | @@ -1,5 +1,5 @@ | |||
292 | 1 | /* | 1 | /* |
294 | 2 | * Copyright 2012, 2013, 2014 Canonical Ltd. | 2 | * Copyright 2012-2015 Canonical Ltd. |
295 | 3 | * | 3 | * |
296 | 4 | * This file is part of messaging-app. | 4 | * This file is part of messaging-app. |
297 | 5 | * | 5 | * |
298 | @@ -18,64 +18,80 @@ | |||
299 | 18 | 18 | ||
300 | 19 | import QtQuick 2.2 | 19 | import QtQuick 2.2 |
301 | 20 | import Ubuntu.Components 1.3 | 20 | import Ubuntu.Components 1.3 |
304 | 21 | import QtMultimedia 5.0 | 21 | import Ubuntu.Thumbnailer 0.1 |
303 | 22 | import ".." | ||
305 | 23 | 22 | ||
306 | 24 | MMSBase { | 23 | MMSBase { |
307 | 25 | id: videoDelegate | 24 | id: videoDelegate |
308 | 26 | 25 | ||
309 | 27 | previewer: "MMS/PreviewerVideo.qml" | 26 | previewer: "MMS/PreviewerVideo.qml" |
313 | 28 | anchors.left: parent.left | 27 | height: videoAttachment.height |
314 | 29 | anchors.right: parent.right | 28 | width: videoAttachment.width |
312 | 30 | height: bubble.height + units.gu(1) | ||
315 | 31 | 29 | ||
317 | 32 | Item { | 30 | UbuntuShape { |
318 | 33 | id: bubble | 31 | id: bubble |
319 | 34 | anchors.top: parent.top | 32 | anchors.top: parent.top |
345 | 35 | width: videoOutput.width + units.gu(3) | 33 | width: image.width |
346 | 36 | height: videoOutput.height + units.gu(2) | 34 | height: image.height |
347 | 37 | 35 | ||
348 | 38 | MediaPlayer { | 36 | image: Image { |
349 | 39 | id: video | 37 | id: videoAttachment |
350 | 40 | autoLoad: true | 38 | objectName: "videoAttachment" |
351 | 41 | autoPlay: false | 39 | |
352 | 42 | source: attachment.filePath | 40 | fillMode: Image.PreserveAspectCrop |
353 | 43 | onStatusChanged: { | 41 | smooth: true |
354 | 44 | if (status === MediaPlayer.Loaded) { | 42 | source: "image://thumbnailer/" + attachment.filePath |
355 | 45 | // FIXME: there is no way to show the thumbnail | 43 | visible: false |
356 | 46 | video.play(); video.stop(); | 44 | asynchronous: true |
357 | 47 | 45 | height: Math.min(implicitHeight, units.gu(14)) | |
358 | 48 | // resize videoOutput, as width is not set | 46 | width: Math.min(implicitWidth, units.gu(27)) |
359 | 49 | // properly when using PreserveAspectFit | 47 | cache: false |
360 | 50 | if (videoOutput.height > units.gu(25)) { | 48 | |
361 | 51 | var percentageResized = units.gu(25)*100/(metaData.resolution.height) | 49 | sourceSize.width: units.gu(27) |
362 | 52 | videoOutput.height = units.gu(25) | 50 | sourceSize.height: units.gu(27) |
363 | 53 | videoOutput.width = (metaData.resolution.width*percentageResized)/100 | 51 | |
364 | 54 | } | 52 | onStatusChanged: { |
365 | 55 | if (videoOutput.width > units.gu(35)) { | 53 | if (status === Image.Error) { |
366 | 56 | percentageResized = units.gu(35)*100/(metaData.resolution.width) | 54 | source = "image://theme/image-missing" |
367 | 57 | videoOutput.width = units.gu(35) | 55 | width = 128 |
368 | 58 | videoOutput.height = (metaData.resolution.height*percentageResized)/100 | 56 | height = 128 |
344 | 59 | } | ||
369 | 60 | } | 57 | } |
370 | 61 | } | 58 | } |
371 | 62 | } | 59 | } |
375 | 63 | VideoOutput { | 60 | |
376 | 64 | id: videoOutput | 61 | Icon { |
377 | 65 | source: video | 62 | objectName: "playbackStartIcon" |
378 | 63 | width: units.gu(3) | ||
379 | 64 | height: units.gu(3) | ||
380 | 66 | anchors.centerIn: parent | 65 | anchors.centerIn: parent |
382 | 67 | anchors.horizontalCenterOffset: incoming ? units.gu(0.5) : -units.gu(0.5) | 66 | name: "media-playback-start" |
383 | 67 | color: "white" | ||
384 | 68 | opacity: 0.8 | ||
385 | 68 | } | 69 | } |
386 | 69 | 70 | ||
387 | 70 | Rectangle { | 71 | Rectangle { |
396 | 71 | color: "black" | 72 | visible: videoDelegate.lastItem |
397 | 72 | opacity: 0.8 | 73 | gradient: Gradient { |
398 | 73 | anchors.fill: videoOutput | 74 | GradientStop { position: 0.0; color: "transparent" } |
399 | 74 | Icon { | 75 | GradientStop { position: 1.0; color: "gray" } |
400 | 75 | name: "media-playback-start" | 76 | } |
401 | 76 | width: units.gu(4) | 77 | |
402 | 77 | height: units.gu(4) | 78 | anchors { |
403 | 78 | anchors.centerIn: parent | 79 | bottom: parent.bottom |
404 | 80 | left: parent.left | ||
405 | 81 | right: parent.right | ||
406 | 82 | } | ||
407 | 83 | height: units.gu(2) | ||
408 | 84 | radius: bubble.height * 0.1 | ||
409 | 85 | Label { | ||
410 | 86 | anchors{ | ||
411 | 87 | left: parent.left | ||
412 | 88 | bottom: parent.bottom | ||
413 | 89 | leftMargin: incoming ? units.gu(2) : units.gu(1) | ||
414 | 90 | bottomMargin: units.gu(0.5) | ||
415 | 91 | } | ||
416 | 92 | fontSize: "xx-small" | ||
417 | 93 | text: Qt.formatTime(timestamp).toLowerCase() | ||
418 | 94 | color: "white" | ||
419 | 79 | } | 95 | } |
420 | 80 | } | 96 | } |
421 | 81 | } | 97 | } |
422 | 82 | 98 | ||
423 | === modified file 'src/qml/MMS/PreviewerImage.qml' | |||
424 | --- src/qml/MMS/PreviewerImage.qml 2015-09-14 13:51:27 +0000 | |||
425 | +++ src/qml/MMS/PreviewerImage.qml 2015-12-08 18:33:04 +0000 | |||
426 | @@ -1,5 +1,5 @@ | |||
427 | 1 | /* | 1 | /* |
429 | 2 | * Copyright 2012, 2013, 2014 Canonical Ltd. | 2 | * Copyright 2012-2015 Canonical Ltd. |
430 | 3 | * | 3 | * |
431 | 4 | * This file is part of messaging-app. | 4 | * This file is part of messaging-app. |
432 | 5 | * | 5 | * |
433 | @@ -19,18 +19,193 @@ | |||
434 | 19 | import QtQuick 2.2 | 19 | import QtQuick 2.2 |
435 | 20 | import Ubuntu.Components 1.3 | 20 | import Ubuntu.Components 1.3 |
436 | 21 | import Ubuntu.Content 0.1 | 21 | import Ubuntu.Content 0.1 |
437 | 22 | import Ubuntu.Thumbnailer 0.1 | ||
438 | 22 | import ".." | 23 | import ".." |
439 | 23 | 24 | ||
440 | 24 | Previewer { | 25 | Previewer { |
441 | 26 | id: imagePreviewer | ||
442 | 27 | |||
443 | 28 | Component.onCompleted: application.fullscreen = true | ||
444 | 29 | Component.onDestruction: application.fullscreen = false | ||
445 | 30 | |||
446 | 31 | Connections { | ||
447 | 32 | target: application | ||
448 | 33 | onFullscreenChanged: imagePreviewer.head.visible = !application.fullscreen | ||
449 | 34 | } | ||
450 | 35 | |||
451 | 25 | title: i18n.tr("Image Preview") | 36 | title: i18n.tr("Image Preview") |
452 | 26 | clip: true | 37 | clip: true |
455 | 27 | Image { | 38 | |
456 | 28 | anchors.centerIn: parent | 39 | Rectangle { |
457 | 29 | anchors.fill: parent | 40 | anchors.fill: parent |
463 | 30 | fillMode: Image.PreserveAspectFit | 41 | color: "black" |
464 | 31 | source: attachment.filePath | 42 | } |
465 | 32 | cache: false | 43 | |
466 | 33 | sourceSize.width: parent.width | 44 | Item { |
467 | 34 | sourceSize.height: parent.height | 45 | id: imageItem |
468 | 46 | property bool pinchInProgress: zoomPinchArea.active | ||
469 | 47 | property size thumbSize: Qt.size(viewer.width * 1.05, viewer.height * 1.05) | ||
470 | 48 | |||
471 | 49 | onWidthChanged: { | ||
472 | 50 | // Only change thumbSize if width increases more than 5% | ||
473 | 51 | // that way we do not reload image for small resizes | ||
474 | 52 | if (width > thumbSize.width) { | ||
475 | 53 | thumbSize = Qt.size(width * 1.05, height * 1.05); | ||
476 | 54 | } | ||
477 | 55 | } | ||
478 | 56 | |||
479 | 57 | onHeightChanged: { | ||
480 | 58 | // Only change thumbSize if height increases more than 5% | ||
481 | 59 | // that way we do not reload image for small resizes | ||
482 | 60 | if (height > thumbSize.height) { | ||
483 | 61 | thumbSize = Qt.size(width * 1.05, height * 1.05); | ||
484 | 62 | } | ||
485 | 63 | } | ||
486 | 64 | |||
487 | 65 | function zoomIn(centerX, centerY, factor) { | ||
488 | 66 | flickable.scaleCenterX = centerX / (flickable.sizeScale * flickable.width); | ||
489 | 67 | flickable.scaleCenterY = centerY / (flickable.sizeScale * flickable.height); | ||
490 | 68 | flickable.sizeScale = factor; | ||
491 | 69 | } | ||
492 | 70 | |||
493 | 71 | function zoomOut() { | ||
494 | 72 | if (flickable.sizeScale != 1.0) { | ||
495 | 73 | flickable.scaleCenterX = flickable.contentX / flickable.width / (flickable.sizeScale - 1); | ||
496 | 74 | flickable.scaleCenterY = flickable.contentY / flickable.height / (flickable.sizeScale - 1); | ||
497 | 75 | flickable.sizeScale = 1.0; | ||
498 | 76 | } | ||
499 | 77 | } | ||
500 | 78 | |||
501 | 79 | width: parent.width | ||
502 | 80 | height: parent.height | ||
503 | 81 | |||
504 | 82 | ActivityIndicator { | ||
505 | 83 | objectName: "imageActivityIndicator" | ||
506 | 84 | anchors.centerIn: parent | ||
507 | 85 | visible: running | ||
508 | 86 | running: image.status != Image.Ready | ||
509 | 87 | } | ||
510 | 88 | |||
511 | 89 | PinchArea { | ||
512 | 90 | id: zoomPinchArea | ||
513 | 91 | anchors.fill: parent | ||
514 | 92 | |||
515 | 93 | property real initialZoom | ||
516 | 94 | property real maximumScale: 3.0 | ||
517 | 95 | property real minimumZoom: 1.0 | ||
518 | 96 | property real maximumZoom: 3.0 | ||
519 | 97 | property bool active: false | ||
520 | 98 | property var center | ||
521 | 99 | |||
522 | 100 | onPinchStarted: { | ||
523 | 101 | active = true; | ||
524 | 102 | initialZoom = flickable.sizeScale; | ||
525 | 103 | center = zoomPinchArea.mapToItem(media, pinch.startCenter.x, pinch.startCenter.y); | ||
526 | 104 | imageItem.zoomIn(center.x, center.y, initialZoom); | ||
527 | 105 | } | ||
528 | 106 | onPinchUpdated: { | ||
529 | 107 | var zoomFactor = MathUtils.clamp(initialZoom * pinch.scale, minimumZoom, maximumZoom); | ||
530 | 108 | flickable.sizeScale = zoomFactor; | ||
531 | 109 | } | ||
532 | 110 | onPinchFinished: { | ||
533 | 111 | active = false; | ||
534 | 112 | } | ||
535 | 113 | |||
536 | 114 | Flickable { | ||
537 | 115 | id: flickable | ||
538 | 116 | anchors.fill: parent | ||
539 | 117 | contentWidth: media.width | ||
540 | 118 | contentHeight: media.height | ||
541 | 119 | contentX: (sizeScale - 1) * scaleCenterX * width | ||
542 | 120 | contentY: (sizeScale - 1) * scaleCenterY * height | ||
543 | 121 | interactive: !imageItem.pinchInProgress | ||
544 | 122 | |||
545 | 123 | property real sizeScale: 1.0 | ||
546 | 124 | property real scaleCenterX: 0.0 | ||
547 | 125 | property real scaleCenterY: 0.0 | ||
548 | 126 | |||
549 | 127 | Behavior on sizeScale { | ||
550 | 128 | enabled: !imageItem.pinchInProgress | ||
551 | 129 | UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} | ||
552 | 130 | } | ||
553 | 131 | Behavior on scaleCenterX { | ||
554 | 132 | UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} | ||
555 | 133 | } | ||
556 | 134 | Behavior on scaleCenterY { | ||
557 | 135 | UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} | ||
558 | 136 | } | ||
559 | 137 | |||
560 | 138 | Item { | ||
561 | 139 | id: media | ||
562 | 140 | |||
563 | 141 | width: flickable.width * flickable.sizeScale | ||
564 | 142 | height: flickable.height * flickable.sizeScale | ||
565 | 143 | |||
566 | 144 | Image { | ||
567 | 145 | id: image | ||
568 | 146 | objectName: "thumbnailImage" | ||
569 | 147 | anchors.fill: parent | ||
570 | 148 | asynchronous: true | ||
571 | 149 | cache: false | ||
572 | 150 | source: "image://thumbnailer/%1".arg(attachment.filePath.toString()) | ||
573 | 151 | sourceSize { | ||
574 | 152 | width: imageItem.thumbSize.width | ||
575 | 153 | height: imageItem.thumbSize.height | ||
576 | 154 | } | ||
577 | 155 | fillMode: Image.PreserveAspectFit | ||
578 | 156 | opacity: status == Image.Ready ? 1.0 : 0.0 | ||
579 | 157 | Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} } | ||
580 | 158 | } | ||
581 | 159 | |||
582 | 160 | Image { | ||
583 | 161 | id: highResolutionImage | ||
584 | 162 | objectName: "highResolutionImage" | ||
585 | 163 | anchors.fill: parent | ||
586 | 164 | asynchronous: true | ||
587 | 165 | cache: false | ||
588 | 166 | source: flickable.sizeScale > 1.0 ? attachment.filePath : "" | ||
589 | 167 | sourceSize { | ||
590 | 168 | width: width | ||
591 | 169 | height: height | ||
592 | 170 | } | ||
593 | 171 | fillMode: Image.PreserveAspectFit | ||
594 | 172 | } | ||
595 | 173 | } | ||
596 | 174 | |||
597 | 175 | MouseArea { | ||
598 | 176 | id: imageMouseArea | ||
599 | 177 | anchors.fill: parent | ||
600 | 178 | |||
601 | 179 | property bool clickAccepted: false | ||
602 | 180 | |||
603 | 181 | onDoubleClicked: { | ||
604 | 182 | if (imageMouseArea.clickAccepted) { | ||
605 | 183 | return | ||
606 | 184 | } | ||
607 | 185 | |||
608 | 186 | clickTimer.stop() | ||
609 | 187 | |||
610 | 188 | if (flickable.sizeScale < zoomPinchArea.maximumZoom) { | ||
611 | 189 | imageItem.zoomIn(mouse.x, mouse.y, zoomPinchArea.maximumZoom); | ||
612 | 190 | } else { | ||
613 | 191 | imageItem.zoomOut(); | ||
614 | 192 | } | ||
615 | 193 | } | ||
616 | 194 | onClicked: { | ||
617 | 195 | imageMouseArea.clickAccepted = false | ||
618 | 196 | clickTimer.start() | ||
619 | 197 | } | ||
620 | 198 | } | ||
621 | 199 | |||
622 | 200 | Timer { | ||
623 | 201 | id: clickTimer | ||
624 | 202 | interval: 200 | ||
625 | 203 | onTriggered: { | ||
626 | 204 | imageMouseArea.clickAccepted = true | ||
627 | 205 | application.fullscreen = !application.fullscreen | ||
628 | 206 | } | ||
629 | 207 | } | ||
630 | 208 | } | ||
631 | 209 | } | ||
632 | 35 | } | 210 | } |
633 | 36 | } | 211 | } |
634 | 37 | 212 | ||
635 | === modified file 'src/qml/MMS/PreviewerVideo.qml' | |||
636 | --- src/qml/MMS/PreviewerVideo.qml 2015-09-14 13:51:27 +0000 | |||
637 | +++ src/qml/MMS/PreviewerVideo.qml 2015-12-08 18:33:04 +0000 | |||
638 | @@ -1,5 +1,5 @@ | |||
639 | 1 | /* | 1 | /* |
641 | 2 | * Copyright 2012, 2013, 2014 Canonical Ltd. | 2 | * Copyright 2012-2015 Canonical Ltd. |
642 | 3 | * | 3 | * |
643 | 4 | * This file is part of messaging-app. | 4 | * This file is part of messaging-app. |
644 | 5 | * | 5 | * |
645 | @@ -17,61 +17,152 @@ | |||
646 | 17 | */ | 17 | */ |
647 | 18 | 18 | ||
648 | 19 | import QtQuick 2.2 | 19 | import QtQuick 2.2 |
649 | 20 | import QtMultimedia 5.0 | ||
650 | 20 | import Ubuntu.Components 1.3 | 21 | import Ubuntu.Components 1.3 |
652 | 21 | import QtMultimedia 5.0 | 22 | import Ubuntu.Content 0.1 |
653 | 23 | import Ubuntu.Thumbnailer 0.1 | ||
654 | 24 | import messagingapp.private 0.1 | ||
655 | 22 | import ".." | 25 | import ".." |
656 | 23 | 26 | ||
657 | 24 | Previewer { | 27 | Previewer { |
658 | 28 | id: videoPreviewer | ||
659 | 29 | |||
660 | 25 | title: i18n.tr("Video Preview") | 30 | title: i18n.tr("Video Preview") |
673 | 26 | // This previewer implements only basic video controls: play/pause/rewind | 31 | clip: true |
674 | 27 | onActionTriggered: video.pause() | 32 | |
675 | 28 | MediaPlayer { | 33 | Component.onCompleted: { |
676 | 29 | id: video | 34 | application.fullscreen = true |
677 | 30 | autoLoad: true | 35 | // Load Video player after toggling fullscreen to reduce flickering |
678 | 31 | autoPlay: true | 36 | videoLoader.active = true |
679 | 32 | source: attachment.filePath | 37 | } |
680 | 33 | } | 38 | Component.onDestruction: application.fullscreen = false |
681 | 34 | VideoOutput { | 39 | |
682 | 35 | id: videoOutput | 40 | Connections { |
683 | 36 | source: video | 41 | target: application |
684 | 37 | anchors.fill: parent | 42 | onFullscreenChanged: { |
685 | 43 | videoPreviewer.head.visible = !application.fullscreen | ||
686 | 44 | toolbar.collapsed = application.fullscreen | ||
687 | 45 | } | ||
688 | 46 | } | ||
689 | 47 | |||
690 | 48 | Rectangle { | ||
691 | 49 | anchors.fill: parent | ||
692 | 50 | color: "black" | ||
693 | 51 | } | ||
694 | 52 | |||
695 | 53 | Loader { | ||
696 | 54 | id: videoLoader | ||
697 | 55 | |||
698 | 56 | anchors.fill: parent | ||
699 | 57 | active: false | ||
700 | 58 | sourceComponent: videoComponent | ||
701 | 59 | |||
702 | 60 | onStatusChanged: { | ||
703 | 61 | if (status == Loader.Ready) { | ||
704 | 62 | var tmpFile = FileOperations.getTemporaryFile(".mp4") | ||
705 | 63 | if (FileOperations.link(attachment.filePath, tmpFile)) { | ||
706 | 64 | videoLoader.item.source = tmpFile | ||
707 | 65 | } else { | ||
708 | 66 | console.log("MMSVideo: Failed to link", attachment.filePath, "to", tmpFile) | ||
709 | 67 | } | ||
710 | 68 | } | ||
711 | 69 | } | ||
712 | 70 | |||
713 | 71 | Component { | ||
714 | 72 | id: videoComponent | ||
715 | 73 | |||
716 | 74 | Item { | ||
717 | 75 | id: videoPlayer | ||
718 | 76 | objectName: "videoPlayer" | ||
719 | 77 | |||
720 | 78 | property alias source: player.source | ||
721 | 79 | property alias playbackState: player.playbackState | ||
722 | 80 | |||
723 | 81 | function play() { player.play() } | ||
724 | 82 | function pause() { player.pause() } | ||
725 | 83 | function stop() { player.stop() } | ||
726 | 84 | |||
727 | 85 | anchors.fill: parent | ||
728 | 86 | |||
729 | 87 | MediaPlayer { | ||
730 | 88 | id: player | ||
731 | 89 | autoPlay: true | ||
732 | 90 | } | ||
733 | 91 | |||
734 | 92 | VideoOutput { | ||
735 | 93 | id: videoOutput | ||
736 | 94 | anchors.fill: parent | ||
737 | 95 | source: player | ||
738 | 96 | } | ||
739 | 97 | } | ||
740 | 98 | } | ||
741 | 38 | } | 99 | } |
742 | 39 | 100 | ||
743 | 40 | MouseArea { | 101 | MouseArea { |
750 | 41 | id: playArea | 102 | anchors { |
751 | 42 | anchors.fill: parent | 103 | top: parent.top |
752 | 43 | onPressed: { | 104 | bottom: toolbar.top |
753 | 44 | if (video.playbackState === MediaPlayer.PlayingState) { | 105 | left: parent.left |
754 | 45 | video.pause() | 106 | right: parent.right |
749 | 46 | } | ||
755 | 47 | } | 107 | } |
756 | 108 | onClicked: application.fullscreen = !application.fullscreen | ||
757 | 48 | } | 109 | } |
758 | 49 | 110 | ||
759 | 50 | Rectangle { | 111 | Rectangle { |
762 | 51 | color: "black" | 112 | id: toolbar |
763 | 52 | visible: video.playbackState !== MediaPlayer.PlayingState | 113 | objectName: "toolbar" |
764 | 114 | |||
765 | 115 | property bool collapsed: false | ||
766 | 116 | |||
767 | 117 | anchors.bottom: parent.bottom | ||
768 | 118 | |||
769 | 119 | width: parent.width | ||
770 | 120 | height: collapsed ? 0 : units.gu(7) | ||
771 | 121 | Behavior on height { UbuntuNumberAnimation {} } | ||
772 | 122 | |||
773 | 123 | color: "gray" | ||
774 | 53 | opacity: 0.8 | 124 | opacity: 0.8 |
776 | 54 | anchors.fill: videoOutput | 125 | |
777 | 55 | Row { | 126 | Row { |
779 | 56 | anchors.centerIn: parent | 127 | anchors { |
780 | 128 | top: parent.top | ||
781 | 129 | bottom: parent.bottom | ||
782 | 130 | horizontalCenter: parent.horizontalCenter | ||
783 | 131 | } | ||
784 | 132 | |||
785 | 133 | spacing: units.gu(2) | ||
786 | 134 | |||
787 | 57 | Icon { | 135 | Icon { |
791 | 58 | name: "media-playback-pause" | 136 | anchors.verticalCenter: parent.verticalCenter |
792 | 59 | width: units.gu(5) | 137 | width: toolbar.collapsed ? 0 : units.gu(5) |
793 | 60 | height: units.gu(5) | 138 | height: width |
794 | 139 | Behavior on width { UbuntuNumberAnimation {} } | ||
795 | 140 | Behavior on height { UbuntuNumberAnimation {} } | ||
796 | 141 | name: videoLoader.item && videoLoader.item.playbackState == MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start" | ||
797 | 142 | color: "white" | ||
798 | 61 | MouseArea { | 143 | MouseArea { |
799 | 62 | anchors.fill: parent | 144 | anchors.fill: parent |
801 | 63 | onClicked: video.play(); | 145 | onClicked: { |
802 | 146 | if (videoLoader.item.playbackState == MediaPlayer.PlayingState) { | ||
803 | 147 | videoLoader.item.pause() | ||
804 | 148 | } else { | ||
805 | 149 | videoLoader.item.play() | ||
806 | 150 | } | ||
807 | 151 | } | ||
808 | 64 | } | 152 | } |
809 | 65 | } | 153 | } |
810 | 66 | Icon { | 154 | Icon { |
814 | 67 | name: "media-seek-backward" | 155 | anchors.verticalCenter: parent.verticalCenter |
815 | 68 | width: units.gu(5) | 156 | width: toolbar.collapsed ? 0 : units.gu(5) |
816 | 69 | height: units.gu(5) | 157 | height: width |
817 | 158 | Behavior on width { UbuntuNumberAnimation {} } | ||
818 | 159 | Behavior on height { UbuntuNumberAnimation {} } | ||
819 | 160 | name: "media-playback-stop" | ||
820 | 161 | color: "white" | ||
821 | 70 | MouseArea { | 162 | MouseArea { |
822 | 71 | anchors.fill: parent | 163 | anchors.fill: parent |
823 | 72 | onClicked: { | 164 | onClicked: { |
826 | 73 | video.stop(); | 165 | videoLoader.item.stop() |
825 | 74 | video.play(); | ||
827 | 75 | } | 166 | } |
828 | 76 | } | 167 | } |
829 | 77 | } | 168 | } |
830 | 78 | 169 | ||
831 | === modified file 'src/qml/MMSDelegate.qml' | |||
832 | --- src/qml/MMSDelegate.qml 2015-11-23 19:51:16 +0000 | |||
833 | +++ src/qml/MMSDelegate.qml 2015-12-08 18:33:04 +0000 | |||
834 | @@ -87,12 +87,6 @@ | |||
835 | 87 | "data": attachment, | 87 | "data": attachment, |
836 | 88 | "delegateSource": "MMS/MMSImage.qml", | 88 | "delegateSource": "MMS/MMSImage.qml", |
837 | 89 | }) | 89 | }) |
838 | 90 | //} else if (startsWith(attachment.contentType, "video/")) { | ||
839 | 91 | // TODO: implement proper video attachment support | ||
840 | 92 | // dataAttachments.push({type: "video", | ||
841 | 93 | // data: attachment, | ||
842 | 94 | // delegateSource: "MMS/MMSVideo.qml", | ||
843 | 95 | // }) | ||
844 | 96 | } else if (startsWith(attachment.contentType, "application/smil") || | 90 | } else if (startsWith(attachment.contentType, "application/smil") || |
845 | 97 | startsWith(attachment.contentType, "application/x-smil")) { | 91 | startsWith(attachment.contentType, "application/x-smil")) { |
846 | 98 | // smil files will always be ignored here | 92 | // smil files will always be ignored here |
847 | @@ -102,6 +96,11 @@ | |||
848 | 102 | "data": attachment, | 96 | "data": attachment, |
849 | 103 | "delegateSource": "MMS/MMSContact.qml" | 97 | "delegateSource": "MMS/MMSContact.qml" |
850 | 104 | }) | 98 | }) |
851 | 99 | } else if (startsWith(attachment.contentType, "video/")) { | ||
852 | 100 | root.dataAttachments.push({"type": "video", | ||
853 | 101 | "data": attachment, | ||
854 | 102 | "delegateSource": "MMS/MMSVideo.qml", | ||
855 | 103 | }) | ||
856 | 105 | } else { | 104 | } else { |
857 | 106 | root.dataAttachments.push({"type": "default", | 105 | root.dataAttachments.push({"type": "default", |
858 | 107 | "data": attachment, | 106 | "data": attachment, |
859 | @@ -221,7 +220,7 @@ | |||
860 | 221 | target: bubbleLoader.item | 220 | target: bubbleLoader.item |
861 | 222 | property: "sender" | 221 | property: "sender" |
862 | 223 | value: messageData.sender.alias !== "" ? messageData.sender.alias : messageData.senderId | 222 | value: messageData.sender.alias !== "" ? messageData.sender.alias : messageData.senderId |
864 | 224 | when: participants.length > 1 && bubbleLoader.status === Loader.Ready && messageData.senderId !== "self" | 223 | when: messageData.participants.length > 1 && bubbleLoader.status === Loader.Ready && messageData.senderId !== "self" |
865 | 225 | } | 224 | } |
866 | 226 | } | 225 | } |
867 | 227 | } | 226 | } |
868 | 228 | 227 | ||
869 | === added file 'src/qml/ThumbnailVideo.qml' | |||
870 | --- src/qml/ThumbnailVideo.qml 1970-01-01 00:00:00 +0000 | |||
871 | +++ src/qml/ThumbnailVideo.qml 2015-12-08 18:33:04 +0000 | |||
872 | @@ -0,0 +1,76 @@ | |||
873 | 1 | /* | ||
874 | 2 | * Copyright 2015 Canonical Ltd. | ||
875 | 3 | * | ||
876 | 4 | * This file is part of messaging-app. | ||
877 | 5 | * | ||
878 | 6 | * messaging-app is free software; you can redistribute it and/or modify | ||
879 | 7 | * it under the terms of the GNU General Public License as published by | ||
880 | 8 | * the Free Software Foundation; version 3. | ||
881 | 9 | * | ||
882 | 10 | * messaging-app is distributed in the hope that it will be useful, | ||
883 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
884 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
885 | 13 | * GNU General Public License for more details. | ||
886 | 14 | * | ||
887 | 15 | * You should have received a copy of the GNU General Public License | ||
888 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
889 | 17 | */ | ||
890 | 18 | |||
891 | 19 | import QtQuick 2.0 | ||
892 | 20 | import Ubuntu.Components 1.3 | ||
893 | 21 | import Ubuntu.Thumbnailer 0.1 | ||
894 | 22 | |||
895 | 23 | UbuntuShape { | ||
896 | 24 | id: thumbnail | ||
897 | 25 | property int index | ||
898 | 26 | property string filePath | ||
899 | 27 | |||
900 | 28 | signal pressAndHold() | ||
901 | 29 | |||
902 | 30 | onFilePathChanged: videoImage.source = "image://thumbnailer/" + filePath | ||
903 | 31 | |||
904 | 32 | width: childrenRect.width | ||
905 | 33 | height: childrenRect.height | ||
906 | 34 | |||
907 | 35 | image: Image { | ||
908 | 36 | id: videoImage | ||
909 | 37 | |||
910 | 38 | width: units.gu(8) | ||
911 | 39 | height: units.gu(8) | ||
912 | 40 | sourceSize.width: width | ||
913 | 41 | sourceSize.height: height | ||
914 | 42 | fillMode: Image.PreserveAspectCrop | ||
915 | 43 | asynchronous: true | ||
916 | 44 | |||
917 | 45 | onStatusChanged: { | ||
918 | 46 | if (status === Image.Error) { | ||
919 | 47 | source = "image://theme/image-missing" | ||
920 | 48 | } | ||
921 | 49 | } | ||
922 | 50 | } | ||
923 | 51 | |||
924 | 52 | ActivityIndicator { | ||
925 | 53 | anchors.centerIn: parent | ||
926 | 54 | visible: running | ||
927 | 55 | running: videoImage.status != Image.Ready | ||
928 | 56 | } | ||
929 | 57 | |||
930 | 58 | Icon { | ||
931 | 59 | width: units.gu(3) | ||
932 | 60 | height: units.gu(3) | ||
933 | 61 | anchors.centerIn: parent | ||
934 | 62 | name: "media-playback-start" | ||
935 | 63 | color: "white" | ||
936 | 64 | visible: opacity > 0.0 | ||
937 | 65 | opacity: videoImage.status == Image.Ready ? 0.8 : 0.0 | ||
938 | 66 | Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} } | ||
939 | 67 | } | ||
940 | 68 | |||
941 | 69 | MouseArea { | ||
942 | 70 | anchors.fill: parent | ||
943 | 71 | onPressAndHold: { | ||
944 | 72 | mouse.accept = true | ||
945 | 73 | thumbnail.pressAndHold() | ||
946 | 74 | } | ||
947 | 75 | } | ||
948 | 76 | } | ||
949 | 0 | 77 | ||
950 | === modified file 'src/qml/messaging-app.qml' | |||
951 | --- src/qml/messaging-app.qml 2015-11-23 19:51:16 +0000 | |||
952 | +++ src/qml/messaging-app.qml 2015-12-08 18:33:04 +0000 | |||
953 | @@ -1,5 +1,5 @@ | |||
954 | 1 | /* | 1 | /* |
956 | 2 | * Copyright 2012-2013 Canonical Ltd. | 2 | * Copyright 2012-2015 Canonical Ltd. |
957 | 3 | * | 3 | * |
958 | 4 | * This file is part of messaging-app. | 4 | * This file is part of messaging-app. |
959 | 5 | * | 5 | * |
960 | @@ -194,6 +194,8 @@ | |||
961 | 194 | } else if (startsWith(contentType, "text/vcard") || | 194 | } else if (startsWith(contentType, "text/vcard") || |
962 | 195 | startsWith(contentType, "text/x-vcard")) { | 195 | startsWith(contentType, "text/x-vcard")) { |
963 | 196 | return ContentType.Contacts | 196 | return ContentType.Contacts |
964 | 197 | } else if (startsWith(contentType, "video/")) { | ||
965 | 198 | return ContentType.Videos | ||
966 | 197 | } | 199 | } |
967 | 198 | return ContentType.Unknown | 200 | return ContentType.Unknown |
968 | 199 | } | 201 | } |
969 | 200 | 202 | ||
970 | === modified file 'tests/qml/CMakeLists.txt' | |||
971 | --- tests/qml/CMakeLists.txt 2015-08-13 18:34:55 +0000 | |||
972 | +++ tests/qml/CMakeLists.txt 2015-12-08 18:33:04 +0000 | |||
973 | @@ -1,33 +1,42 @@ | |||
979 | 1 | find_program(QMLTESTRUNNER_BIN | 1 | find_package(Qt5Core REQUIRED) |
980 | 2 | NAMES qmltestrunner | 2 | find_package(Qt5Qml REQUIRED) |
981 | 3 | PATHS /usr/lib/*/qt5/bin | 3 | find_package(Qt5Quick REQUIRED) |
982 | 4 | NO_DEFAULT_PATH | 4 | find_package(Qt5QuickTest REQUIRED) |
983 | 5 | ) | 5 | |
984 | 6 | set(XVFB_COMMAND) | ||
985 | 6 | 7 | ||
986 | 7 | find_program(XVFB_RUN_BIN | 8 | find_program(XVFB_RUN_BIN |
987 | 8 | NAMES xvfb-run | 9 | NAMES xvfb-run |
988 | 9 | ) | 10 | ) |
989 | 10 | 11 | ||
1000 | 11 | macro(DECLARE_QML_TEST TST_NAME TST_QML_FILE) | 12 | if(XVFB_RUN_BIN) |
1001 | 12 | add_test(NAME ${TST_NAME} | 13 | set(XVFB_COMMAND ${XVFB_RUN_BIN} -s "-screen 0 1024x768x24" -a) |
992 | 13 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} | ||
993 | 14 | COMMAND ${XVFB_RUN_BIN} -a -s "-screen 0 1024x768x24" ${QMLTESTRUNNER_BIN} -import ${qml_BINARY_DIR} -input ${CMAKE_CURRENT_SOURCE_DIR}/${TST_QML_FILE} | ||
994 | 15 | ) | ||
995 | 16 | endmacro() | ||
996 | 17 | |||
997 | 18 | if(QMLTESTRUNNER_BIN AND XVFB_RUN_BIN) | ||
998 | 19 | declare_qml_test("message_bubble" tst_MessageBubble.qml) | ||
999 | 20 | declare_qml_test("messages_view" tst_MessagesView.qml) | ||
1002 | 21 | else() | 14 | else() |
1008 | 22 | if (NOT QMLTESTRUNNER_BIN) | 15 | message(WARNING "Qml tests disabled: xvfb-run not found") |
1004 | 23 | message(WARNING "Qml tests disabled: qmltestrunner not found") | ||
1005 | 24 | else() | ||
1006 | 25 | message(WARNING "Qml tests disabled: xvfb-run not found") | ||
1007 | 26 | endif() | ||
1009 | 27 | endif() | 16 | endif() |
1010 | 28 | 17 | ||
1016 | 29 | set(QML_TST_FILES | 18 | set(TEST tst_QmlTests) |
1017 | 30 | tst_MessageBubble.qml | 19 | |
1018 | 31 | tst_MessagesView.qml | 20 | set(SOURCES |
1019 | 32 | ) | 21 | ${messaging-app_SOURCE_DIR}/src/fileoperations.cpp |
1020 | 33 | add_custom_target(tst_QmlFiles ALL SOURCES ${QML_TST_FILES}) | 22 | tst_QmlTests.cpp |
1021 | 23 | ) | ||
1022 | 24 | |||
1023 | 25 | add_executable(${TEST} ${SOURCES}) | ||
1024 | 26 | |||
1025 | 27 | include_directories( | ||
1026 | 28 | ${messaging-app_SOURCE_DIR}/src | ||
1027 | 29 | ${CMAKE_CURRENT_BINARY_DIR} | ||
1028 | 30 | ${CMAKE_CURRENT_SOURCE_DIR} | ||
1029 | 31 | ) | ||
1030 | 32 | |||
1031 | 33 | target_link_libraries(${TEST} | ||
1032 | 34 | Qt5::Core | ||
1033 | 35 | Qt5::Qml | ||
1034 | 36 | Qt5::Quick | ||
1035 | 37 | Qt5::QuickTest | ||
1036 | 38 | ) | ||
1037 | 39 | |||
1038 | 40 | add_test(${TEST} ${XVFB_COMMAND} ${CMAKE_CURRENT_BINARY_DIR}/${TEST} | ||
1039 | 41 | -input ${CMAKE_CURRENT_SOURCE_DIR} | ||
1040 | 42 | -import ${CMAKE_BINARY_DIR}/src) | ||
1041 | 34 | 43 | ||
1042 | === added directory 'tests/qml/data' | |||
1043 | === added file 'tests/qml/data/sample.mp4' | |||
1044 | 35 | Binary files tests/qml/data/sample.mp4 1970-01-01 00:00:00 +0000 and tests/qml/data/sample.mp4 2015-12-08 18:33:04 +0000 differ | 44 | Binary files tests/qml/data/sample.mp4 1970-01-01 00:00:00 +0000 and tests/qml/data/sample.mp4 2015-12-08 18:33:04 +0000 differ |
1045 | === added file 'tests/qml/data/sample.png' | |||
1046 | 36 | Binary files tests/qml/data/sample.png 1970-01-01 00:00:00 +0000 and tests/qml/data/sample.png 2015-12-08 18:33:04 +0000 differ | 45 | Binary files tests/qml/data/sample.png 1970-01-01 00:00:00 +0000 and tests/qml/data/sample.png 2015-12-08 18:33:04 +0000 differ |
1047 | === added file 'tests/qml/tst_MMSDelegate.qml' | |||
1048 | --- tests/qml/tst_MMSDelegate.qml 1970-01-01 00:00:00 +0000 | |||
1049 | +++ tests/qml/tst_MMSDelegate.qml 2015-12-08 18:33:04 +0000 | |||
1050 | @@ -0,0 +1,167 @@ | |||
1051 | 1 | /* | ||
1052 | 2 | * Copyright 2015 Canonical Ltd. | ||
1053 | 3 | * | ||
1054 | 4 | * Authors: | ||
1055 | 5 | * Arthur Mello <arthur.mello@canonical.com> | ||
1056 | 6 | * | ||
1057 | 7 | * This file is part of messaging-app. | ||
1058 | 8 | * | ||
1059 | 9 | * messaging-app is free software; you can redistribute it and/or modify | ||
1060 | 10 | * it under the terms of the GNU General Public License as published by | ||
1061 | 11 | * the Free Software Foundation; version 3. | ||
1062 | 12 | * | ||
1063 | 13 | * messaging-app is distributed in the hope that it will be useful, | ||
1064 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1065 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1066 | 16 | * GNU General Public License for more details. | ||
1067 | 17 | * | ||
1068 | 18 | * You should have received a copy of the GNU General Public License | ||
1069 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1070 | 20 | */ | ||
1071 | 21 | |||
1072 | 22 | import QtQuick 2.2 | ||
1073 | 23 | import QtTest 1.0 | ||
1074 | 24 | import Ubuntu.Test 0.1 | ||
1075 | 25 | |||
1076 | 26 | import '../../src/qml/' | ||
1077 | 27 | |||
1078 | 28 | Item { | ||
1079 | 29 | id: root | ||
1080 | 30 | |||
1081 | 31 | width: units.gu(40) | ||
1082 | 32 | height: units.gu(40) | ||
1083 | 33 | |||
1084 | 34 | MMSDelegate { | ||
1085 | 35 | id: mmsDelegate | ||
1086 | 36 | objectName: "mmsDelegate" | ||
1087 | 37 | |||
1088 | 38 | function startsWith(str, prefix) { | ||
1089 | 39 | return str.toLowerCase().slice(0, prefix.length) === prefix.toLowerCase(); | ||
1090 | 40 | } | ||
1091 | 41 | |||
1092 | 42 | anchors.fill: parent | ||
1093 | 43 | |||
1094 | 44 | messageData: { | ||
1095 | 45 | "participants": [], | ||
1096 | 46 | "sender": {"alias": ""}, | ||
1097 | 47 | "textMessageAttachments": [], | ||
1098 | 48 | } | ||
1099 | 49 | } | ||
1100 | 50 | |||
1101 | 51 | UbuntuTestCase { | ||
1102 | 52 | id: mmsImageDelegateTestCase | ||
1103 | 53 | name: 'mmsImageDelegateTestCase' | ||
1104 | 54 | |||
1105 | 55 | when: windowShown | ||
1106 | 56 | |||
1107 | 57 | function test_load_image() { | ||
1108 | 58 | mmsDelegate.messageData = { | ||
1109 | 59 | "newEvent": false, | ||
1110 | 60 | "participants": [], | ||
1111 | 61 | "sender": {"alias": ""}, | ||
1112 | 62 | "senderId": "self", | ||
1113 | 63 | "textMessage": "Message Delegate QML Test", | ||
1114 | 64 | "textMessageAttachments": [ | ||
1115 | 65 | { | ||
1116 | 66 | "contentType": "image/png", | ||
1117 | 67 | "filePath": Qt.resolvedUrl("./data/sample.png") | ||
1118 | 68 | } | ||
1119 | 69 | ], | ||
1120 | 70 | "textMessageStatus": 1, | ||
1121 | 71 | "textReadTimestamp": new Date(), | ||
1122 | 72 | "timestamp": new Date() | ||
1123 | 73 | } | ||
1124 | 74 | |||
1125 | 75 | var image = findChild(mmsDelegate, "imageAttachment") | ||
1126 | 76 | verify(image != null) | ||
1127 | 77 | waitForRendering(image) | ||
1128 | 78 | verify(image.source != "image://theme/image-missing") | ||
1129 | 79 | } | ||
1130 | 80 | |||
1131 | 81 | function test_load_invalid_path() { | ||
1132 | 82 | mmsDelegate.messageData = { | ||
1133 | 83 | "newEvent": false, | ||
1134 | 84 | "participants": [], | ||
1135 | 85 | "sender": {"alias": ""}, | ||
1136 | 86 | "senderId": "self", | ||
1137 | 87 | "textMessage": "Message Delegate QML Test", | ||
1138 | 88 | "textMessageAttachments": [ | ||
1139 | 89 | { | ||
1140 | 90 | "contentType": "image/png", | ||
1141 | 91 | "filePath": "/wrong/path/file.png" | ||
1142 | 92 | } | ||
1143 | 93 | ], | ||
1144 | 94 | "textMessageStatus": 1, | ||
1145 | 95 | "textReadTimestamp": new Date(), | ||
1146 | 96 | "timestamp": new Date() | ||
1147 | 97 | } | ||
1148 | 98 | |||
1149 | 99 | var image = findChild(mmsDelegate, "imageAttachment") | ||
1150 | 100 | verify(image != null) | ||
1151 | 101 | waitForRendering(image) | ||
1152 | 102 | compare(image.source, "image://theme/image-missing") | ||
1153 | 103 | } | ||
1154 | 104 | } | ||
1155 | 105 | |||
1156 | 106 | UbuntuTestCase { | ||
1157 | 107 | id: mmsVideoDelegateTestCase | ||
1158 | 108 | name: 'mmsVideoDelegateTestCase' | ||
1159 | 109 | |||
1160 | 110 | when: windowShown | ||
1161 | 111 | |||
1162 | 112 | |||
1163 | 113 | function test_load_video() { | ||
1164 | 114 | mmsDelegate.messageData = { | ||
1165 | 115 | "newEvent": false, | ||
1166 | 116 | "participants": [], | ||
1167 | 117 | "sender": {"alias": ""}, | ||
1168 | 118 | "senderId": "self", | ||
1169 | 119 | "textMessage": "Message Delegate QML Test", | ||
1170 | 120 | "textMessageAttachments": [ | ||
1171 | 121 | { | ||
1172 | 122 | "contentType": "video/mp4", | ||
1173 | 123 | "filePath": Qt.resolvedUrl("./data/sample.mp4") | ||
1174 | 124 | } | ||
1175 | 125 | ], | ||
1176 | 126 | "textMessageStatus": 1, | ||
1177 | 127 | "textReadTimestamp": new Date(), | ||
1178 | 128 | "timestamp": new Date() | ||
1179 | 129 | } | ||
1180 | 130 | |||
1181 | 131 | var video = findChild(mmsDelegate, "videoAttachment") | ||
1182 | 132 | verify(video != null) | ||
1183 | 133 | waitForRendering(video) | ||
1184 | 134 | verify(video.source != "image://theme/image-missing") | ||
1185 | 135 | |||
1186 | 136 | var icon = findChild(mmsDelegate, "playbackStartIcon") | ||
1187 | 137 | verify(icon != null) | ||
1188 | 138 | waitForRendering(icon) | ||
1189 | 139 | verify(icon.visible) | ||
1190 | 140 | } | ||
1191 | 141 | |||
1192 | 142 | function test_load_invalid_path() { | ||
1193 | 143 | skip("image://thumbnailer is not reporting an error for wrong file path") | ||
1194 | 144 | mmsDelegate.messageData = { | ||
1195 | 145 | "newEvent": false, | ||
1196 | 146 | "participants": [], | ||
1197 | 147 | "sender": {"alias": ""}, | ||
1198 | 148 | "senderId": "self", | ||
1199 | 149 | "textMessage": "Message Delegate QML Test", | ||
1200 | 150 | "textMessageAttachments": [ | ||
1201 | 151 | { | ||
1202 | 152 | "contentType": "video/mp4", | ||
1203 | 153 | "filePath": "/wrong/path/file.mp4" | ||
1204 | 154 | } | ||
1205 | 155 | ], | ||
1206 | 156 | "textMessageStatus": 1, | ||
1207 | 157 | "textReadTimestamp": new Date(), | ||
1208 | 158 | "timestamp": new Date() | ||
1209 | 159 | } | ||
1210 | 160 | |||
1211 | 161 | var video = findChild(mmsDelegate, "videoAttachment") | ||
1212 | 162 | verify(video != null) | ||
1213 | 163 | waitForRendering(video) | ||
1214 | 164 | compare(video.source, "image://theme/image-missing") | ||
1215 | 165 | } | ||
1216 | 166 | } | ||
1217 | 167 | } | ||
1218 | 0 | 168 | ||
1219 | === added file 'tests/qml/tst_PreviewerImage.qml' | |||
1220 | --- tests/qml/tst_PreviewerImage.qml 1970-01-01 00:00:00 +0000 | |||
1221 | +++ tests/qml/tst_PreviewerImage.qml 2015-12-08 18:33:04 +0000 | |||
1222 | @@ -0,0 +1,103 @@ | |||
1223 | 1 | /* | ||
1224 | 2 | * Copyright 2015 Canonical Ltd. | ||
1225 | 3 | * | ||
1226 | 4 | * Authors: | ||
1227 | 5 | * Arthur Mello <arthur.mello@canonical.com> | ||
1228 | 6 | * | ||
1229 | 7 | * This file is part of messaging-app. | ||
1230 | 8 | * | ||
1231 | 9 | * messaging-app is free software; you can redistribute it and/or modify | ||
1232 | 10 | * it under the terms of the GNU General Public License as published by | ||
1233 | 11 | * the Free Software Foundation; version 3. | ||
1234 | 12 | * | ||
1235 | 13 | * messaging-app is distributed in the hope that it will be useful, | ||
1236 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1237 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1238 | 16 | * GNU General Public License for more details. | ||
1239 | 17 | * | ||
1240 | 18 | * You should have received a copy of the GNU General Public License | ||
1241 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1242 | 20 | */ | ||
1243 | 21 | |||
1244 | 22 | import QtQuick 2.2 | ||
1245 | 23 | import QtTest 1.0 | ||
1246 | 24 | import Ubuntu.Test 0.1 | ||
1247 | 25 | |||
1248 | 26 | import '../../src/qml/MMS' | ||
1249 | 27 | |||
1250 | 28 | Item { | ||
1251 | 29 | id: root | ||
1252 | 30 | |||
1253 | 31 | width: units.gu(40) | ||
1254 | 32 | height: units.gu(40) | ||
1255 | 33 | |||
1256 | 34 | PreviewerImage { | ||
1257 | 35 | id: previewerImage | ||
1258 | 36 | objectName: "previewerImage" | ||
1259 | 37 | |||
1260 | 38 | property var application: QtObject { | ||
1261 | 39 | property bool fullscreen: false | ||
1262 | 40 | } | ||
1263 | 41 | |||
1264 | 42 | anchors.fill: parent | ||
1265 | 43 | |||
1266 | 44 | attachment: { | ||
1267 | 45 | "contentType": "image/png", | ||
1268 | 46 | "filePath": Qt.resolvedUrl("./data/sample.png") | ||
1269 | 47 | } | ||
1270 | 48 | } | ||
1271 | 49 | |||
1272 | 50 | UbuntuTestCase { | ||
1273 | 51 | id: previewerImageTestCase | ||
1274 | 52 | name: 'peviewerImageTestCase' | ||
1275 | 53 | |||
1276 | 54 | when: windowShown | ||
1277 | 55 | |||
1278 | 56 | function test_load_image() { | ||
1279 | 57 | var activityIndicator = findChild(previewerImage, "imageActivityIndicator") | ||
1280 | 58 | verify(activityIndicator != null) | ||
1281 | 59 | tryCompare(activityIndicator, "visible", false) | ||
1282 | 60 | |||
1283 | 61 | var thumbnail = findChild(previewerImage, "thumbnailImage") | ||
1284 | 62 | verify(thumbnail != null) | ||
1285 | 63 | tryCompare(thumbnail, "opacity", 1.0) | ||
1286 | 64 | |||
1287 | 65 | var highRes = findChild(previewerImage, "highResolutionImage") | ||
1288 | 66 | verify(highRes != null) | ||
1289 | 67 | compare(highRes.source, "") | ||
1290 | 68 | } | ||
1291 | 69 | |||
1292 | 70 | function test_zoom_in_out() { | ||
1293 | 71 | var activityIndicator = findChild(previewerImage, "imageActivityIndicator") | ||
1294 | 72 | verify(activityIndicator != null) | ||
1295 | 73 | tryCompare(activityIndicator, "visible", false) | ||
1296 | 74 | |||
1297 | 75 | var thumbnail = findChild(previewerImage, "thumbnailImage") | ||
1298 | 76 | verify(thumbnail != null) | ||
1299 | 77 | tryCompare(thumbnail, "opacity", 1.0) | ||
1300 | 78 | |||
1301 | 79 | var highRes = findChild(previewerImage, "highResolutionImage") | ||
1302 | 80 | verify(highRes != null) | ||
1303 | 81 | compare(highRes.source, "") | ||
1304 | 82 | |||
1305 | 83 | mouseDoubleClick(thumbnail) | ||
1306 | 84 | verify(highRes.source !== "") | ||
1307 | 85 | |||
1308 | 86 | mouseDoubleClick(thumbnail) | ||
1309 | 87 | compare(highRes.source, "") | ||
1310 | 88 | } | ||
1311 | 89 | |||
1312 | 90 | function test_toggle_fullscreen() { | ||
1313 | 91 | var activityIndicator = findChild(previewerImage, "imageActivityIndicator") | ||
1314 | 92 | verify(activityIndicator != null) | ||
1315 | 93 | tryCompare(activityIndicator, "visible", false) | ||
1316 | 94 | |||
1317 | 95 | var thumbnail = findChild(previewerImage, "thumbnailImage") | ||
1318 | 96 | verify(thumbnail != null) | ||
1319 | 97 | |||
1320 | 98 | verify(previewerImage.application.fullscreen) | ||
1321 | 99 | mouseClick(thumbnail) | ||
1322 | 100 | tryCompare(previewerImage.application, "fullscreen", false) | ||
1323 | 101 | } | ||
1324 | 102 | } | ||
1325 | 103 | } | ||
1326 | 0 | 104 | ||
1327 | === added file 'tests/qml/tst_PreviewerVideo.qml' | |||
1328 | --- tests/qml/tst_PreviewerVideo.qml 1970-01-01 00:00:00 +0000 | |||
1329 | +++ tests/qml/tst_PreviewerVideo.qml 2015-12-08 18:33:04 +0000 | |||
1330 | @@ -0,0 +1,87 @@ | |||
1331 | 1 | /* | ||
1332 | 2 | * Copyright 2015 Canonical Ltd. | ||
1333 | 3 | * | ||
1334 | 4 | * Authors: | ||
1335 | 5 | * Arthur Mello <arthur.mello@canonical.com> | ||
1336 | 6 | * | ||
1337 | 7 | * This file is part of messaging-app. | ||
1338 | 8 | * | ||
1339 | 9 | * messaging-app is free software; you can redistribute it and/or modify | ||
1340 | 10 | * it under the terms of the GNU General Public License as published by | ||
1341 | 11 | * the Free Software Foundation; version 3. | ||
1342 | 12 | * | ||
1343 | 13 | * messaging-app is distributed in the hope that it will be useful, | ||
1344 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1345 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1346 | 16 | * GNU General Public License for more details. | ||
1347 | 17 | * | ||
1348 | 18 | * You should have received a copy of the GNU General Public License | ||
1349 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1350 | 20 | */ | ||
1351 | 21 | |||
1352 | 22 | import QtQuick 2.2 | ||
1353 | 23 | import QtTest 1.0 | ||
1354 | 24 | import Ubuntu.Content 0.1 | ||
1355 | 25 | import Ubuntu.Test 0.1 | ||
1356 | 26 | |||
1357 | 27 | import '../../src/qml/MMS' | ||
1358 | 28 | |||
1359 | 29 | Item { | ||
1360 | 30 | id: root | ||
1361 | 31 | |||
1362 | 32 | width: units.gu(40) | ||
1363 | 33 | height: units.gu(40) | ||
1364 | 34 | |||
1365 | 35 | PreviewerVideo { | ||
1366 | 36 | id: previewerVideo | ||
1367 | 37 | objectName: "previewerVideo" | ||
1368 | 38 | |||
1369 | 39 | property var application: QtObject { | ||
1370 | 40 | property bool fullscreen: false | ||
1371 | 41 | } | ||
1372 | 42 | |||
1373 | 43 | function getContentType(filePath) { | ||
1374 | 44 | return ContentType.Videos | ||
1375 | 45 | } | ||
1376 | 46 | |||
1377 | 47 | anchors.fill: parent | ||
1378 | 48 | |||
1379 | 49 | attachment: { | ||
1380 | 50 | "contentType": "video/mp4", | ||
1381 | 51 | "filePath": Qt.resolvedUrl("./data/sample.mp4") | ||
1382 | 52 | } | ||
1383 | 53 | } | ||
1384 | 54 | |||
1385 | 55 | UbuntuTestCase { | ||
1386 | 56 | id: previewerVideoTestCase | ||
1387 | 57 | name: 'peviewerVideoTestCase' | ||
1388 | 58 | |||
1389 | 59 | when: windowShown | ||
1390 | 60 | |||
1391 | 61 | function test_load_video() { | ||
1392 | 62 | var videoPlayer = findChild(previewerVideo, "videoPlayer") | ||
1393 | 63 | verify(videoPlayer != null) | ||
1394 | 64 | tryCompare(videoPlayer, "visible", true) | ||
1395 | 65 | |||
1396 | 66 | var toolbar = findChild(previewerVideo, "toolbar") | ||
1397 | 67 | verify(toolbar != null) | ||
1398 | 68 | tryCompare(toolbar, "collapsed", true) | ||
1399 | 69 | } | ||
1400 | 70 | |||
1401 | 71 | function test_toggle_toolbar() { | ||
1402 | 72 | var videoPlayer = findChild(previewerVideo, "videoPlayer") | ||
1403 | 73 | verify(videoPlayer != null) | ||
1404 | 74 | tryCompare(videoPlayer, "visible", true) | ||
1405 | 75 | |||
1406 | 76 | var toolbar = findChild(previewerVideo, "toolbar") | ||
1407 | 77 | verify(toolbar != null) | ||
1408 | 78 | tryCompare(toolbar, "collapsed", true) | ||
1409 | 79 | |||
1410 | 80 | mouseClick(videoPlayer) | ||
1411 | 81 | tryCompare(toolbar, "collapsed", false) | ||
1412 | 82 | |||
1413 | 83 | mouseClick(videoPlayer) | ||
1414 | 84 | tryCompare(toolbar, "collapsed", true) | ||
1415 | 85 | } | ||
1416 | 86 | } | ||
1417 | 87 | } | ||
1418 | 0 | 88 | ||
1419 | === added file 'tests/qml/tst_QmlTests.cpp' | |||
1420 | --- tests/qml/tst_QmlTests.cpp 1970-01-01 00:00:00 +0000 | |||
1421 | +++ tests/qml/tst_QmlTests.cpp 2015-12-08 18:33:04 +0000 | |||
1422 | @@ -0,0 +1,61 @@ | |||
1423 | 1 | /* | ||
1424 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
1425 | 3 | * | ||
1426 | 4 | * Authors: | ||
1427 | 5 | * Arthur Mello <arthur.mello@canonical.com> | ||
1428 | 6 | * | ||
1429 | 7 | * This file is part of messaging-app. | ||
1430 | 8 | * | ||
1431 | 9 | * messaging-app is free software; you can redistribute it and/or modify | ||
1432 | 10 | * it under the terms of the GNU General Public License as published by | ||
1433 | 11 | * the Free Software Foundation; version 3. | ||
1434 | 12 | * | ||
1435 | 13 | * messaging-app is distributed in the hope that it will be useful, | ||
1436 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1437 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1438 | 16 | * GNU General Public License for more details. | ||
1439 | 17 | * | ||
1440 | 18 | * You should have received a copy of the GNU General Public License | ||
1441 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1442 | 20 | */ | ||
1443 | 21 | |||
1444 | 22 | // Qt | ||
1445 | 23 | #include <QtQuickTest/QtQuickTest> | ||
1446 | 24 | #include <QtQml/QtQml> | ||
1447 | 25 | |||
1448 | 26 | // local | ||
1449 | 27 | #include "fileoperations.h" | ||
1450 | 28 | |||
1451 | 29 | class TestContext : public QObject | ||
1452 | 30 | { | ||
1453 | 31 | Q_OBJECT | ||
1454 | 32 | |||
1455 | 33 | public: | ||
1456 | 34 | explicit TestContext(QObject* parent=0) | ||
1457 | 35 | : QObject(parent) | ||
1458 | 36 | {} | ||
1459 | 37 | }; | ||
1460 | 38 | |||
1461 | 39 | static QObject* TestContext_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) | ||
1462 | 40 | { | ||
1463 | 41 | Q_UNUSED(engine); | ||
1464 | 42 | Q_UNUSED(scriptEngine); | ||
1465 | 43 | return new TestContext(); | ||
1466 | 44 | } | ||
1467 | 45 | |||
1468 | 46 | static QObject* FileOperations_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) | ||
1469 | 47 | { | ||
1470 | 48 | Q_UNUSED(engine); | ||
1471 | 49 | Q_UNUSED(scriptEngine); | ||
1472 | 50 | return new FileOperations(); | ||
1473 | 51 | } | ||
1474 | 52 | |||
1475 | 53 | int main(int argc, char** argv) | ||
1476 | 54 | { | ||
1477 | 55 | qmlRegisterSingletonType<FileOperations>("messagingapp.private", 0, 1, "FileOperations", FileOperations_singleton_factory); | ||
1478 | 56 | qmlRegisterSingletonType<TestContext>("messagingtest.private", 0, 1, "TestContext", TestContext_singleton_factory); | ||
1479 | 57 | |||
1480 | 58 | return quick_test_main(argc, argv, "QmlTests", 0); | ||
1481 | 59 | } | ||
1482 | 60 | |||
1483 | 61 | #include "tst_QmlTests.moc" |
FAILED: Continuous integration, rev:476 jenkins. qa.ubuntu. com/job/ messaging- app-ci/ 749/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 5392/console jenkins. qa.ubuntu. com/job/ messaging- app-vivid- i386-ci/ 258/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 5406/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/ 749/rebuild
http://