Merge lp:~artmello/messaging-app/messaging-app-video_attachment into lp:messaging-app

Proposed by Arthur Mello
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
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

To post a comment you must log in.
476. By Arthur Mello

Update headers

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
477. By Arthur Mello

Add initial qml test

478. By Arthur Mello

Change on MMSDelegate to look for participants from messageData

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tiago Salem Herrmann (tiagosh) :
review: Needs Fixing
479. By Arthur Mello

Add QML tests for MMSDelegate

480. By Arthur Mello

Add PreviewerImage QML tests

481. By Arthur Mello

Merge with lp:~boiko/messaging-app/more_attachment_types/

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
482. By Arthur Mello

Add TODO message for FileOperations
Remove mimetype check used for testing

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
483. By Arthur Mello

Change QML test structure so we could include messaingapp.private

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
484. By Arthur Mello

Fix build

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
485. By Arthur Mello

Add PreviewerVideo qml tests

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
492. By Arthur Mello

Merge with lp:~boiko/messaging-app/more_attachment_types

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
496. By Arthur Mello

Use VideoOutput instead of Video QML component

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
497. By Arthur Mello

Merge with parent branch

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
498. By Arthur Mello

Merge with parent branch

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2015-09-11 14:25:57 +0000
+++ debian/control 2015-12-08 18:33:04 +0000
@@ -21,8 +21,10 @@
21 qtdeclarative5-ubuntu-telephony0.1 | qtdeclarative5-ubuntu-telephony-plugin,21 qtdeclarative5-ubuntu-telephony0.1 | qtdeclarative5-ubuntu-telephony-plugin,
22 qtdeclarative5-ubuntu-content1,22 qtdeclarative5-ubuntu-content1,
23 qtdeclarative5-ubuntu-addressbook0.1,23 qtdeclarative5-ubuntu-addressbook0.1,
24 qtdeclarative5-ubuntu-thumbnailer0.1,
24 qtdeclarative5-qtcontacts-plugin,25 qtdeclarative5-qtcontacts-plugin,
25 qml-module-qt-labs-settings,26 qml-module-qt-labs-settings,
27 qml-module-qtmultimedia,
26 qtpim5-dev,28 qtpim5-dev,
27 xvfb,29 xvfb,
28Standards-Version: 3.9.430Standards-Version: 3.9.4
2931
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2015-02-24 13:33:31 +0000
+++ src/CMakeLists.txt 2015-12-08 18:33:04 +0000
@@ -1,10 +1,12 @@
1set(MESSAGING_APP messaging-app)1set(MESSAGING_APP messaging-app)
22
3set(messaging_app_HDRS3set(messaging_app_HDRS
4 fileoperations.h
4 messagingapplication.h5 messagingapplication.h
5 )6 )
67
7set(messaging_app_SRCS8set(messaging_app_SRCS
9 fileoperations.cpp
8 messagingapplication.cpp10 messagingapplication.cpp
9 main.cpp11 main.cpp
10 )12 )
1113
=== added file 'src/fileoperations.cpp'
--- src/fileoperations.cpp 1970-01-01 00:00:00 +0000
+++ src/fileoperations.cpp 2015-12-08 18:33:04 +0000
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * Authors:
5 * Arthur Mello <arthur.mello@canonical.com>
6 *
7 * This file is part of messaging-app.
8 *
9 * messaging-app is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * messaging-app is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "fileoperations.h"
23
24#include <QDir>
25#include <QFile>
26#include <QTemporaryFile>
27
28FileOperations::FileOperations(QObject *parent)
29 : QObject(parent)
30{
31}
32
33FileOperations::~FileOperations()
34{
35}
36
37QString FileOperations::getTemporaryFile(const QString &fileExtension) const
38{
39 //TODO remove once lp:1420728 is fixed
40 QTemporaryFile tmp(QDir::tempPath() + "/tmpXXXXXX" + fileExtension);
41 tmp.open();
42 return tmp.fileName();
43}
44
45bool FileOperations::link(const QString &from, const QString &to)
46{
47 return QFile::link(from, to);
48}
049
=== added file 'src/fileoperations.h'
--- src/fileoperations.h 1970-01-01 00:00:00 +0000
+++ src/fileoperations.h 2015-12-08 18:33:04 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * Authors:
5 * Arthur Mello <arthur.mello@canonical.com>
6 *
7 * This file is part of messaging-app.
8 *
9 * messaging-app is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * messaging-app is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#ifndef FILEOPERATIONS_H
23#define FILEOPERATIONS_H
24
25#include <QObject>
26
27class FileOperations : public QObject
28{
29 Q_OBJECT
30
31public:
32 FileOperations(QObject *parent = 0);
33 ~FileOperations();
34
35 Q_INVOKABLE QString getTemporaryFile(const QString &fileExtension) const;
36 Q_INVOKABLE bool link(const QString &from, const QString &to);
37};
38
39#endif // FILEOPERATIONS_H
040
=== modified file 'src/messagingapplication.cpp'
--- src/messagingapplication.cpp 2015-11-23 19:51:16 +0000
+++ src/messagingapplication.cpp 2015-12-08 18:33:04 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2012 Canonical, Ltd.2 * Copyright (C) 2012-2015 Canonical, Ltd.
3 *3 *
4 * This file is part of messaging-app.4 * This file is part of messaging-app.
5 *5 *
@@ -17,6 +17,7 @@
17 */17 */
1818
19#include "messagingapplication.h"19#include "messagingapplication.h"
20#include "fileoperations.h"
2021
21#include <libnotify/notify.h>22#include <libnotify/notify.h>
2223
@@ -65,12 +66,24 @@
65 }66 }
66}67}
6768
69static QObject* FileOperations_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine)
70{
71 Q_UNUSED(engine);
72 Q_UNUSED(scriptEngine);
73 return new FileOperations();
74}
75
68MessagingApplication::MessagingApplication(int &argc, char **argv)76MessagingApplication::MessagingApplication(int &argc, char **argv)
69 : QGuiApplication(argc, argv), m_view(0), m_applicationIsReady(false)77 : QGuiApplication(argc, argv), m_view(0), m_applicationIsReady(false)
70{78{
71 setApplicationName("MessagingApp");79 setApplicationName("MessagingApp");
72}80}
7381
82bool MessagingApplication::fullscreen() const
83{
84 return m_view->windowState() == Qt::WindowFullScreen;
85}
86
74bool MessagingApplication::setup()87bool MessagingApplication::setup()
75{88{
76 installIconPath();89 installIconPath();
@@ -133,6 +146,9 @@
133 }146 }
134 }147 }
135148
149 const char* uri = "messagingapp.private";
150 qmlRegisterSingletonType<FileOperations>(uri, 0, 1, "FileOperations", FileOperations_singleton_factory);
151
136 m_view = new QQuickView();152 m_view = new QQuickView();
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)));
138 QObject::connect(m_view->engine(), SIGNAL(quit()), SLOT(quit()));154 QObject::connect(m_view->engine(), SIGNAL(quit()), SLOT(quit()));
@@ -176,6 +192,17 @@
176 }192 }
177}193}
178194
195void MessagingApplication::setFullscreen(bool fullscreen)
196{
197 if (fullscreen) {
198 m_view->setWindowState(Qt::WindowFullScreen);
199 } else {
200 m_view->setWindowState(Qt::WindowNoState);
201 }
202
203 Q_EMIT fullscreenChanged();
204}
205
179void MessagingApplication::onViewStatusChanged(QQuickView::Status status)206void MessagingApplication::onViewStatusChanged(QQuickView::Status status)
180{207{
181 if (status != QQuickView::Ready) {208 if (status != QQuickView::Ready) {
182209
=== modified file 'src/messagingapplication.h'
--- src/messagingapplication.h 2015-11-18 16:36:51 +0000
+++ src/messagingapplication.h 2015-12-08 18:33:04 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2012-2013 Canonical, Ltd.2 * Copyright (C) 2012-2015 Canonical, Ltd.
3 *3 *
4 * This file is part of messaging-app.4 * This file is part of messaging-app.
5 *5 *
@@ -26,13 +26,18 @@
26class MessagingApplication : public QGuiApplication26class MessagingApplication : public QGuiApplication
27{27{
28 Q_OBJECT28 Q_OBJECT
29 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
2930
30public:31public:
31 MessagingApplication(int &argc, char **argv);32 MessagingApplication(int &argc, char **argv);
32 virtual ~MessagingApplication();33 virtual ~MessagingApplication();
3334
35 bool fullscreen() const;
34 bool setup();36 bool setup();
3537
38Q_SIGNALS:
39 void fullscreenChanged();
40
36public Q_SLOTS:41public Q_SLOTS:
37 void activateWindow();42 void activateWindow();
38 void parseArgument(const QString &arg);43 void parseArgument(const QString &arg);
@@ -41,6 +46,7 @@
41 void showNotificationMessage(const QString &message, const QString &icon = QString());46 void showNotificationMessage(const QString &message, const QString &icon = QString());
4247
43private Q_SLOTS:48private Q_SLOTS:
49 void setFullscreen(bool fullscreen);
44 void onViewStatusChanged(QQuickView::Status status);50 void onViewStatusChanged(QQuickView::Status status);
45 void onApplicationReady();51 void onApplicationReady();
4652
4753
=== modified file 'src/qml/AttachmentPanel.qml'
--- src/qml/AttachmentPanel.qml 2015-12-08 18:33:04 +0000
+++ src/qml/AttachmentPanel.qml 2015-12-08 18:33:04 +0000
@@ -102,8 +102,7 @@
102 }102 }
103 }103 }
104104
105 // FIXME: re-enable that once we have proper delegates105 TransparentButton {
106 /*TransparentButton {
107 id: videoButton106 id: videoButton
108 objectName: "videoButton"107 objectName: "videoButton"
109 iconName: "stock_video"108 iconName: "stock_video"
@@ -114,7 +113,7 @@
114 onClicked: {113 onClicked: {
115 contentImporter.requestVideo()114 contentImporter.requestVideo()
116 }115 }
117 }*/116 }
118117
119 // FIXME: enable generic file sharing if we ever support it118 // FIXME: enable generic file sharing if we ever support it
120 /*TransparentButton {119 /*TransparentButton {
121120
=== modified file 'src/qml/ComposeBar.qml'
--- src/qml/ComposeBar.qml 2015-12-08 18:33:04 +0000
+++ src/qml/ComposeBar.qml 2015-12-08 18:33:04 +0000
@@ -204,6 +204,8 @@
204 return Qt.resolvedUrl("ThumbnailContact.qml")204 return Qt.resolvedUrl("ThumbnailContact.qml")
205 case ContentType.Pictures:205 case ContentType.Pictures:
206 return Qt.resolvedUrl("ThumbnailImage.qml")206 return Qt.resolvedUrl("ThumbnailImage.qml")
207 case ContentType.Videos:
208 return Qt.resolvedUrl("ThumbnailVideo.qml")
207 case ContentType.Unknown:209 case ContentType.Unknown:
208 return Qt.resolvedUrl("ThumbnailUnknown.qml")210 return Qt.resolvedUrl("ThumbnailUnknown.qml")
209 default:211 default:
210212
=== modified file 'src/qml/MMS/MMSImage.qml'
--- src/qml/MMS/MMSImage.qml 2015-09-14 13:51:27 +0000
+++ src/qml/MMS/MMSImage.qml 2015-12-08 18:33:04 +0000
@@ -34,6 +34,7 @@
3434
35 image: Image {35 image: Image {
36 id: imageAttachment36 id: imageAttachment
37 objectName: "imageAttachment"
3738
38 fillMode: Image.PreserveAspectCrop39 fillMode: Image.PreserveAspectCrop
39 smooth: true40 smooth: true
4041
=== modified file 'src/qml/MMS/MMSVideo.qml'
--- src/qml/MMS/MMSVideo.qml 2015-09-14 13:51:27 +0000
+++ src/qml/MMS/MMSVideo.qml 2015-12-08 18:33:04 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012, 2013, 2014 Canonical Ltd.2 * Copyright 2012-2015 Canonical Ltd.
3 *3 *
4 * This file is part of messaging-app.4 * This file is part of messaging-app.
5 *5 *
@@ -18,64 +18,80 @@
1818
19import QtQuick 2.219import QtQuick 2.2
20import Ubuntu.Components 1.320import Ubuntu.Components 1.3
21import QtMultimedia 5.021import Ubuntu.Thumbnailer 0.1
22import ".."
2322
24MMSBase {23MMSBase {
25 id: videoDelegate24 id: videoDelegate
2625
27 previewer: "MMS/PreviewerVideo.qml"26 previewer: "MMS/PreviewerVideo.qml"
28 anchors.left: parent.left27 height: videoAttachment.height
29 anchors.right: parent.right28 width: videoAttachment.width
30 height: bubble.height + units.gu(1)
3129
32 Item {30 UbuntuShape {
33 id: bubble31 id: bubble
34 anchors.top: parent.top32 anchors.top: parent.top
35 width: videoOutput.width + units.gu(3)33 width: image.width
36 height: videoOutput.height + units.gu(2)34 height: image.height
3735
38 MediaPlayer {36 image: Image {
39 id: video37 id: videoAttachment
40 autoLoad: true38 objectName: "videoAttachment"
41 autoPlay: false39
42 source: attachment.filePath40 fillMode: Image.PreserveAspectCrop
43 onStatusChanged: {41 smooth: true
44 if (status === MediaPlayer.Loaded) {42 source: "image://thumbnailer/" + attachment.filePath
45 // FIXME: there is no way to show the thumbnail43 visible: false
46 video.play(); video.stop();44 asynchronous: true
4745 height: Math.min(implicitHeight, units.gu(14))
48 // resize videoOutput, as width is not set46 width: Math.min(implicitWidth, units.gu(27))
49 // properly when using PreserveAspectFit47 cache: false
50 if (videoOutput.height > units.gu(25)) {48
51 var percentageResized = units.gu(25)*100/(metaData.resolution.height)49 sourceSize.width: units.gu(27)
52 videoOutput.height = units.gu(25)50 sourceSize.height: units.gu(27)
53 videoOutput.width = (metaData.resolution.width*percentageResized)/10051
54 }52 onStatusChanged: {
55 if (videoOutput.width > units.gu(35)) {53 if (status === Image.Error) {
56 percentageResized = units.gu(35)*100/(metaData.resolution.width)54 source = "image://theme/image-missing"
57 videoOutput.width = units.gu(35)55 width = 128
58 videoOutput.height = (metaData.resolution.height*percentageResized)/10056 height = 128
59 }
60 }57 }
61 }58 }
62 }59 }
63 VideoOutput {60
64 id: videoOutput61 Icon {
65 source: video62 objectName: "playbackStartIcon"
63 width: units.gu(3)
64 height: units.gu(3)
66 anchors.centerIn: parent65 anchors.centerIn: parent
67 anchors.horizontalCenterOffset: incoming ? units.gu(0.5) : -units.gu(0.5)66 name: "media-playback-start"
67 color: "white"
68 opacity: 0.8
68 }69 }
6970
70 Rectangle {71 Rectangle {
71 color: "black"72 visible: videoDelegate.lastItem
72 opacity: 0.873 gradient: Gradient {
73 anchors.fill: videoOutput74 GradientStop { position: 0.0; color: "transparent" }
74 Icon {75 GradientStop { position: 1.0; color: "gray" }
75 name: "media-playback-start"76 }
76 width: units.gu(4)77
77 height: units.gu(4)78 anchors {
78 anchors.centerIn: parent79 bottom: parent.bottom
80 left: parent.left
81 right: parent.right
82 }
83 height: units.gu(2)
84 radius: bubble.height * 0.1
85 Label {
86 anchors{
87 left: parent.left
88 bottom: parent.bottom
89 leftMargin: incoming ? units.gu(2) : units.gu(1)
90 bottomMargin: units.gu(0.5)
91 }
92 fontSize: "xx-small"
93 text: Qt.formatTime(timestamp).toLowerCase()
94 color: "white"
79 }95 }
80 }96 }
81 }97 }
8298
=== modified file 'src/qml/MMS/PreviewerImage.qml'
--- src/qml/MMS/PreviewerImage.qml 2015-09-14 13:51:27 +0000
+++ src/qml/MMS/PreviewerImage.qml 2015-12-08 18:33:04 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012, 2013, 2014 Canonical Ltd.2 * Copyright 2012-2015 Canonical Ltd.
3 *3 *
4 * This file is part of messaging-app.4 * This file is part of messaging-app.
5 *5 *
@@ -19,18 +19,193 @@
19import QtQuick 2.219import QtQuick 2.2
20import Ubuntu.Components 1.320import Ubuntu.Components 1.3
21import Ubuntu.Content 0.121import Ubuntu.Content 0.1
22import Ubuntu.Thumbnailer 0.1
22import ".."23import ".."
2324
24Previewer {25Previewer {
26 id: imagePreviewer
27
28 Component.onCompleted: application.fullscreen = true
29 Component.onDestruction: application.fullscreen = false
30
31 Connections {
32 target: application
33 onFullscreenChanged: imagePreviewer.head.visible = !application.fullscreen
34 }
35
25 title: i18n.tr("Image Preview")36 title: i18n.tr("Image Preview")
26 clip: true37 clip: true
27 Image {38
28 anchors.centerIn: parent39 Rectangle {
29 anchors.fill: parent40 anchors.fill: parent
30 fillMode: Image.PreserveAspectFit41 color: "black"
31 source: attachment.filePath42 }
32 cache: false43
33 sourceSize.width: parent.width44 Item {
34 sourceSize.height: parent.height45 id: imageItem
46 property bool pinchInProgress: zoomPinchArea.active
47 property size thumbSize: Qt.size(viewer.width * 1.05, viewer.height * 1.05)
48
49 onWidthChanged: {
50 // Only change thumbSize if width increases more than 5%
51 // that way we do not reload image for small resizes
52 if (width > thumbSize.width) {
53 thumbSize = Qt.size(width * 1.05, height * 1.05);
54 }
55 }
56
57 onHeightChanged: {
58 // Only change thumbSize if height increases more than 5%
59 // that way we do not reload image for small resizes
60 if (height > thumbSize.height) {
61 thumbSize = Qt.size(width * 1.05, height * 1.05);
62 }
63 }
64
65 function zoomIn(centerX, centerY, factor) {
66 flickable.scaleCenterX = centerX / (flickable.sizeScale * flickable.width);
67 flickable.scaleCenterY = centerY / (flickable.sizeScale * flickable.height);
68 flickable.sizeScale = factor;
69 }
70
71 function zoomOut() {
72 if (flickable.sizeScale != 1.0) {
73 flickable.scaleCenterX = flickable.contentX / flickable.width / (flickable.sizeScale - 1);
74 flickable.scaleCenterY = flickable.contentY / flickable.height / (flickable.sizeScale - 1);
75 flickable.sizeScale = 1.0;
76 }
77 }
78
79 width: parent.width
80 height: parent.height
81
82 ActivityIndicator {
83 objectName: "imageActivityIndicator"
84 anchors.centerIn: parent
85 visible: running
86 running: image.status != Image.Ready
87 }
88
89 PinchArea {
90 id: zoomPinchArea
91 anchors.fill: parent
92
93 property real initialZoom
94 property real maximumScale: 3.0
95 property real minimumZoom: 1.0
96 property real maximumZoom: 3.0
97 property bool active: false
98 property var center
99
100 onPinchStarted: {
101 active = true;
102 initialZoom = flickable.sizeScale;
103 center = zoomPinchArea.mapToItem(media, pinch.startCenter.x, pinch.startCenter.y);
104 imageItem.zoomIn(center.x, center.y, initialZoom);
105 }
106 onPinchUpdated: {
107 var zoomFactor = MathUtils.clamp(initialZoom * pinch.scale, minimumZoom, maximumZoom);
108 flickable.sizeScale = zoomFactor;
109 }
110 onPinchFinished: {
111 active = false;
112 }
113
114 Flickable {
115 id: flickable
116 anchors.fill: parent
117 contentWidth: media.width
118 contentHeight: media.height
119 contentX: (sizeScale - 1) * scaleCenterX * width
120 contentY: (sizeScale - 1) * scaleCenterY * height
121 interactive: !imageItem.pinchInProgress
122
123 property real sizeScale: 1.0
124 property real scaleCenterX: 0.0
125 property real scaleCenterY: 0.0
126
127 Behavior on sizeScale {
128 enabled: !imageItem.pinchInProgress
129 UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
130 }
131 Behavior on scaleCenterX {
132 UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
133 }
134 Behavior on scaleCenterY {
135 UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
136 }
137
138 Item {
139 id: media
140
141 width: flickable.width * flickable.sizeScale
142 height: flickable.height * flickable.sizeScale
143
144 Image {
145 id: image
146 objectName: "thumbnailImage"
147 anchors.fill: parent
148 asynchronous: true
149 cache: false
150 source: "image://thumbnailer/%1".arg(attachment.filePath.toString())
151 sourceSize {
152 width: imageItem.thumbSize.width
153 height: imageItem.thumbSize.height
154 }
155 fillMode: Image.PreserveAspectFit
156 opacity: status == Image.Ready ? 1.0 : 0.0
157 Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} }
158 }
159
160 Image {
161 id: highResolutionImage
162 objectName: "highResolutionImage"
163 anchors.fill: parent
164 asynchronous: true
165 cache: false
166 source: flickable.sizeScale > 1.0 ? attachment.filePath : ""
167 sourceSize {
168 width: width
169 height: height
170 }
171 fillMode: Image.PreserveAspectFit
172 }
173 }
174
175 MouseArea {
176 id: imageMouseArea
177 anchors.fill: parent
178
179 property bool clickAccepted: false
180
181 onDoubleClicked: {
182 if (imageMouseArea.clickAccepted) {
183 return
184 }
185
186 clickTimer.stop()
187
188 if (flickable.sizeScale < zoomPinchArea.maximumZoom) {
189 imageItem.zoomIn(mouse.x, mouse.y, zoomPinchArea.maximumZoom);
190 } else {
191 imageItem.zoomOut();
192 }
193 }
194 onClicked: {
195 imageMouseArea.clickAccepted = false
196 clickTimer.start()
197 }
198 }
199
200 Timer {
201 id: clickTimer
202 interval: 200
203 onTriggered: {
204 imageMouseArea.clickAccepted = true
205 application.fullscreen = !application.fullscreen
206 }
207 }
208 }
209 }
35 }210 }
36}211}
37212
=== modified file 'src/qml/MMS/PreviewerVideo.qml'
--- src/qml/MMS/PreviewerVideo.qml 2015-09-14 13:51:27 +0000
+++ src/qml/MMS/PreviewerVideo.qml 2015-12-08 18:33:04 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012, 2013, 2014 Canonical Ltd.2 * Copyright 2012-2015 Canonical Ltd.
3 *3 *
4 * This file is part of messaging-app.4 * This file is part of messaging-app.
5 *5 *
@@ -17,61 +17,152 @@
17 */17 */
1818
19import QtQuick 2.219import QtQuick 2.2
20import QtMultimedia 5.0
20import Ubuntu.Components 1.321import Ubuntu.Components 1.3
21import QtMultimedia 5.022import Ubuntu.Content 0.1
23import Ubuntu.Thumbnailer 0.1
24import messagingapp.private 0.1
22import ".."25import ".."
2326
24Previewer {27Previewer {
28 id: videoPreviewer
29
25 title: i18n.tr("Video Preview")30 title: i18n.tr("Video Preview")
26 // This previewer implements only basic video controls: play/pause/rewind31 clip: true
27 onActionTriggered: video.pause()32
28 MediaPlayer {33 Component.onCompleted: {
29 id: video34 application.fullscreen = true
30 autoLoad: true35 // Load Video player after toggling fullscreen to reduce flickering
31 autoPlay: true36 videoLoader.active = true
32 source: attachment.filePath37 }
33 }38 Component.onDestruction: application.fullscreen = false
34 VideoOutput {39
35 id: videoOutput40 Connections {
36 source: video41 target: application
37 anchors.fill: parent42 onFullscreenChanged: {
43 videoPreviewer.head.visible = !application.fullscreen
44 toolbar.collapsed = application.fullscreen
45 }
46 }
47
48 Rectangle {
49 anchors.fill: parent
50 color: "black"
51 }
52
53 Loader {
54 id: videoLoader
55
56 anchors.fill: parent
57 active: false
58 sourceComponent: videoComponent
59
60 onStatusChanged: {
61 if (status == Loader.Ready) {
62 var tmpFile = FileOperations.getTemporaryFile(".mp4")
63 if (FileOperations.link(attachment.filePath, tmpFile)) {
64 videoLoader.item.source = tmpFile
65 } else {
66 console.log("MMSVideo: Failed to link", attachment.filePath, "to", tmpFile)
67 }
68 }
69 }
70
71 Component {
72 id: videoComponent
73
74 Item {
75 id: videoPlayer
76 objectName: "videoPlayer"
77
78 property alias source: player.source
79 property alias playbackState: player.playbackState
80
81 function play() { player.play() }
82 function pause() { player.pause() }
83 function stop() { player.stop() }
84
85 anchors.fill: parent
86
87 MediaPlayer {
88 id: player
89 autoPlay: true
90 }
91
92 VideoOutput {
93 id: videoOutput
94 anchors.fill: parent
95 source: player
96 }
97 }
98 }
38 }99 }
39100
40 MouseArea {101 MouseArea {
41 id: playArea102 anchors {
42 anchors.fill: parent103 top: parent.top
43 onPressed: {104 bottom: toolbar.top
44 if (video.playbackState === MediaPlayer.PlayingState) {105 left: parent.left
45 video.pause()106 right: parent.right
46 }
47 }107 }
108 onClicked: application.fullscreen = !application.fullscreen
48 }109 }
49110
50 Rectangle {111 Rectangle {
51 color: "black"112 id: toolbar
52 visible: video.playbackState !== MediaPlayer.PlayingState113 objectName: "toolbar"
114
115 property bool collapsed: false
116
117 anchors.bottom: parent.bottom
118
119 width: parent.width
120 height: collapsed ? 0 : units.gu(7)
121 Behavior on height { UbuntuNumberAnimation {} }
122
123 color: "gray"
53 opacity: 0.8124 opacity: 0.8
54 anchors.fill: videoOutput125
55 Row {126 Row {
56 anchors.centerIn: parent127 anchors {
128 top: parent.top
129 bottom: parent.bottom
130 horizontalCenter: parent.horizontalCenter
131 }
132
133 spacing: units.gu(2)
134
57 Icon {135 Icon {
58 name: "media-playback-pause"136 anchors.verticalCenter: parent.verticalCenter
59 width: units.gu(5)137 width: toolbar.collapsed ? 0 : units.gu(5)
60 height: units.gu(5)138 height: width
139 Behavior on width { UbuntuNumberAnimation {} }
140 Behavior on height { UbuntuNumberAnimation {} }
141 name: videoLoader.item && videoLoader.item.playbackState == MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start"
142 color: "white"
61 MouseArea {143 MouseArea {
62 anchors.fill: parent144 anchors.fill: parent
63 onClicked: video.play();145 onClicked: {
146 if (videoLoader.item.playbackState == MediaPlayer.PlayingState) {
147 videoLoader.item.pause()
148 } else {
149 videoLoader.item.play()
150 }
151 }
64 }152 }
65 }153 }
66 Icon {154 Icon {
67 name: "media-seek-backward"155 anchors.verticalCenter: parent.verticalCenter
68 width: units.gu(5)156 width: toolbar.collapsed ? 0 : units.gu(5)
69 height: units.gu(5)157 height: width
158 Behavior on width { UbuntuNumberAnimation {} }
159 Behavior on height { UbuntuNumberAnimation {} }
160 name: "media-playback-stop"
161 color: "white"
70 MouseArea {162 MouseArea {
71 anchors.fill: parent163 anchors.fill: parent
72 onClicked: {164 onClicked: {
73 video.stop();165 videoLoader.item.stop()
74 video.play();
75 }166 }
76 }167 }
77 }168 }
78169
=== modified file 'src/qml/MMSDelegate.qml'
--- src/qml/MMSDelegate.qml 2015-11-23 19:51:16 +0000
+++ src/qml/MMSDelegate.qml 2015-12-08 18:33:04 +0000
@@ -87,12 +87,6 @@
87 "data": attachment,87 "data": attachment,
88 "delegateSource": "MMS/MMSImage.qml",88 "delegateSource": "MMS/MMSImage.qml",
89 })89 })
90 //} else if (startsWith(attachment.contentType, "video/")) {
91 // TODO: implement proper video attachment support
92 // dataAttachments.push({type: "video",
93 // data: attachment,
94 // delegateSource: "MMS/MMSVideo.qml",
95 // })
96 } else if (startsWith(attachment.contentType, "application/smil") ||90 } else if (startsWith(attachment.contentType, "application/smil") ||
97 startsWith(attachment.contentType, "application/x-smil")) {91 startsWith(attachment.contentType, "application/x-smil")) {
98 // smil files will always be ignored here92 // smil files will always be ignored here
@@ -102,6 +96,11 @@
102 "data": attachment,96 "data": attachment,
103 "delegateSource": "MMS/MMSContact.qml"97 "delegateSource": "MMS/MMSContact.qml"
104 })98 })
99 } else if (startsWith(attachment.contentType, "video/")) {
100 root.dataAttachments.push({"type": "video",
101 "data": attachment,
102 "delegateSource": "MMS/MMSVideo.qml",
103 })
105 } else {104 } else {
106 root.dataAttachments.push({"type": "default",105 root.dataAttachments.push({"type": "default",
107 "data": attachment,106 "data": attachment,
@@ -221,7 +220,7 @@
221 target: bubbleLoader.item220 target: bubbleLoader.item
222 property: "sender"221 property: "sender"
223 value: messageData.sender.alias !== "" ? messageData.sender.alias : messageData.senderId222 value: messageData.sender.alias !== "" ? messageData.sender.alias : messageData.senderId
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"
225 }224 }
226 }225 }
227 }226 }
228227
=== added file 'src/qml/ThumbnailVideo.qml'
--- src/qml/ThumbnailVideo.qml 1970-01-01 00:00:00 +0000
+++ src/qml/ThumbnailVideo.qml 2015-12-08 18:33:04 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of messaging-app.
5 *
6 * messaging-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * messaging-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 1.3
21import Ubuntu.Thumbnailer 0.1
22
23UbuntuShape {
24 id: thumbnail
25 property int index
26 property string filePath
27
28 signal pressAndHold()
29
30 onFilePathChanged: videoImage.source = "image://thumbnailer/" + filePath
31
32 width: childrenRect.width
33 height: childrenRect.height
34
35 image: Image {
36 id: videoImage
37
38 width: units.gu(8)
39 height: units.gu(8)
40 sourceSize.width: width
41 sourceSize.height: height
42 fillMode: Image.PreserveAspectCrop
43 asynchronous: true
44
45 onStatusChanged: {
46 if (status === Image.Error) {
47 source = "image://theme/image-missing"
48 }
49 }
50 }
51
52 ActivityIndicator {
53 anchors.centerIn: parent
54 visible: running
55 running: videoImage.status != Image.Ready
56 }
57
58 Icon {
59 width: units.gu(3)
60 height: units.gu(3)
61 anchors.centerIn: parent
62 name: "media-playback-start"
63 color: "white"
64 visible: opacity > 0.0
65 opacity: videoImage.status == Image.Ready ? 0.8 : 0.0
66 Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} }
67 }
68
69 MouseArea {
70 anchors.fill: parent
71 onPressAndHold: {
72 mouse.accept = true
73 thumbnail.pressAndHold()
74 }
75 }
76}
077
=== modified file 'src/qml/messaging-app.qml'
--- src/qml/messaging-app.qml 2015-11-23 19:51:16 +0000
+++ src/qml/messaging-app.qml 2015-12-08 18:33:04 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012-2013 Canonical Ltd.2 * Copyright 2012-2015 Canonical Ltd.
3 *3 *
4 * This file is part of messaging-app.4 * This file is part of messaging-app.
5 *5 *
@@ -194,6 +194,8 @@
194 } else if (startsWith(contentType, "text/vcard") ||194 } else if (startsWith(contentType, "text/vcard") ||
195 startsWith(contentType, "text/x-vcard")) {195 startsWith(contentType, "text/x-vcard")) {
196 return ContentType.Contacts196 return ContentType.Contacts
197 } else if (startsWith(contentType, "video/")) {
198 return ContentType.Videos
197 }199 }
198 return ContentType.Unknown200 return ContentType.Unknown
199 }201 }
200202
=== modified file 'tests/qml/CMakeLists.txt'
--- tests/qml/CMakeLists.txt 2015-08-13 18:34:55 +0000
+++ tests/qml/CMakeLists.txt 2015-12-08 18:33:04 +0000
@@ -1,33 +1,42 @@
1find_program(QMLTESTRUNNER_BIN1find_package(Qt5Core REQUIRED)
2 NAMES qmltestrunner2find_package(Qt5Qml REQUIRED)
3 PATHS /usr/lib/*/qt5/bin3find_package(Qt5Quick REQUIRED)
4 NO_DEFAULT_PATH4find_package(Qt5QuickTest REQUIRED)
5)5
6set(XVFB_COMMAND)
67
7find_program(XVFB_RUN_BIN8find_program(XVFB_RUN_BIN
8 NAMES xvfb-run9 NAMES xvfb-run
9)10)
1011
11macro(DECLARE_QML_TEST TST_NAME TST_QML_FILE)12if(XVFB_RUN_BIN)
12 add_test(NAME ${TST_NAME}13 set(XVFB_COMMAND ${XVFB_RUN_BIN} -s "-screen 0 1024x768x24" -a)
13 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
14 COMMAND ${XVFB_RUN_BIN} -a -s "-screen 0 1024x768x24" ${QMLTESTRUNNER_BIN} -import ${qml_BINARY_DIR} -input ${CMAKE_CURRENT_SOURCE_DIR}/${TST_QML_FILE}
15 )
16endmacro()
17
18if(QMLTESTRUNNER_BIN AND XVFB_RUN_BIN)
19 declare_qml_test("message_bubble" tst_MessageBubble.qml)
20 declare_qml_test("messages_view" tst_MessagesView.qml)
21else()14else()
22 if (NOT QMLTESTRUNNER_BIN)15 message(WARNING "Qml tests disabled: xvfb-run not found")
23 message(WARNING "Qml tests disabled: qmltestrunner not found")
24 else()
25 message(WARNING "Qml tests disabled: xvfb-run not found")
26 endif()
27endif()16endif()
2817
29set(QML_TST_FILES18set(TEST tst_QmlTests)
30 tst_MessageBubble.qml19
31 tst_MessagesView.qml20set(SOURCES
32)21 ${messaging-app_SOURCE_DIR}/src/fileoperations.cpp
33add_custom_target(tst_QmlFiles ALL SOURCES ${QML_TST_FILES})22 tst_QmlTests.cpp
23)
24
25add_executable(${TEST} ${SOURCES})
26
27include_directories(
28 ${messaging-app_SOURCE_DIR}/src
29 ${CMAKE_CURRENT_BINARY_DIR}
30 ${CMAKE_CURRENT_SOURCE_DIR}
31)
32
33target_link_libraries(${TEST}
34 Qt5::Core
35 Qt5::Qml
36 Qt5::Quick
37 Qt5::QuickTest
38)
39
40add_test(${TEST} ${XVFB_COMMAND} ${CMAKE_CURRENT_BINARY_DIR}/${TEST}
41 -input ${CMAKE_CURRENT_SOURCE_DIR}
42 -import ${CMAKE_BINARY_DIR}/src)
3443
=== added directory 'tests/qml/data'
=== added file 'tests/qml/data/sample.mp4'
35Binary 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 differ44Binary 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
=== added file 'tests/qml/data/sample.png'
36Binary 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 differ45Binary 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
=== added file 'tests/qml/tst_MMSDelegate.qml'
--- tests/qml/tst_MMSDelegate.qml 1970-01-01 00:00:00 +0000
+++ tests/qml/tst_MMSDelegate.qml 2015-12-08 18:33:04 +0000
@@ -0,0 +1,167 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * Authors:
5 * Arthur Mello <arthur.mello@canonical.com>
6 *
7 * This file is part of messaging-app.
8 *
9 * messaging-app is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * messaging-app is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22import QtQuick 2.2
23import QtTest 1.0
24import Ubuntu.Test 0.1
25
26import '../../src/qml/'
27
28Item {
29 id: root
30
31 width: units.gu(40)
32 height: units.gu(40)
33
34 MMSDelegate {
35 id: mmsDelegate
36 objectName: "mmsDelegate"
37
38 function startsWith(str, prefix) {
39 return str.toLowerCase().slice(0, prefix.length) === prefix.toLowerCase();
40 }
41
42 anchors.fill: parent
43
44 messageData: {
45 "participants": [],
46 "sender": {"alias": ""},
47 "textMessageAttachments": [],
48 }
49 }
50
51 UbuntuTestCase {
52 id: mmsImageDelegateTestCase
53 name: 'mmsImageDelegateTestCase'
54
55 when: windowShown
56
57 function test_load_image() {
58 mmsDelegate.messageData = {
59 "newEvent": false,
60 "participants": [],
61 "sender": {"alias": ""},
62 "senderId": "self",
63 "textMessage": "Message Delegate QML Test",
64 "textMessageAttachments": [
65 {
66 "contentType": "image/png",
67 "filePath": Qt.resolvedUrl("./data/sample.png")
68 }
69 ],
70 "textMessageStatus": 1,
71 "textReadTimestamp": new Date(),
72 "timestamp": new Date()
73 }
74
75 var image = findChild(mmsDelegate, "imageAttachment")
76 verify(image != null)
77 waitForRendering(image)
78 verify(image.source != "image://theme/image-missing")
79 }
80
81 function test_load_invalid_path() {
82 mmsDelegate.messageData = {
83 "newEvent": false,
84 "participants": [],
85 "sender": {"alias": ""},
86 "senderId": "self",
87 "textMessage": "Message Delegate QML Test",
88 "textMessageAttachments": [
89 {
90 "contentType": "image/png",
91 "filePath": "/wrong/path/file.png"
92 }
93 ],
94 "textMessageStatus": 1,
95 "textReadTimestamp": new Date(),
96 "timestamp": new Date()
97 }
98
99 var image = findChild(mmsDelegate, "imageAttachment")
100 verify(image != null)
101 waitForRendering(image)
102 compare(image.source, "image://theme/image-missing")
103 }
104 }
105
106 UbuntuTestCase {
107 id: mmsVideoDelegateTestCase
108 name: 'mmsVideoDelegateTestCase'
109
110 when: windowShown
111
112
113 function test_load_video() {
114 mmsDelegate.messageData = {
115 "newEvent": false,
116 "participants": [],
117 "sender": {"alias": ""},
118 "senderId": "self",
119 "textMessage": "Message Delegate QML Test",
120 "textMessageAttachments": [
121 {
122 "contentType": "video/mp4",
123 "filePath": Qt.resolvedUrl("./data/sample.mp4")
124 }
125 ],
126 "textMessageStatus": 1,
127 "textReadTimestamp": new Date(),
128 "timestamp": new Date()
129 }
130
131 var video = findChild(mmsDelegate, "videoAttachment")
132 verify(video != null)
133 waitForRendering(video)
134 verify(video.source != "image://theme/image-missing")
135
136 var icon = findChild(mmsDelegate, "playbackStartIcon")
137 verify(icon != null)
138 waitForRendering(icon)
139 verify(icon.visible)
140 }
141
142 function test_load_invalid_path() {
143 skip("image://thumbnailer is not reporting an error for wrong file path")
144 mmsDelegate.messageData = {
145 "newEvent": false,
146 "participants": [],
147 "sender": {"alias": ""},
148 "senderId": "self",
149 "textMessage": "Message Delegate QML Test",
150 "textMessageAttachments": [
151 {
152 "contentType": "video/mp4",
153 "filePath": "/wrong/path/file.mp4"
154 }
155 ],
156 "textMessageStatus": 1,
157 "textReadTimestamp": new Date(),
158 "timestamp": new Date()
159 }
160
161 var video = findChild(mmsDelegate, "videoAttachment")
162 verify(video != null)
163 waitForRendering(video)
164 compare(video.source, "image://theme/image-missing")
165 }
166 }
167}
0168
=== added file 'tests/qml/tst_PreviewerImage.qml'
--- tests/qml/tst_PreviewerImage.qml 1970-01-01 00:00:00 +0000
+++ tests/qml/tst_PreviewerImage.qml 2015-12-08 18:33:04 +0000
@@ -0,0 +1,103 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * Authors:
5 * Arthur Mello <arthur.mello@canonical.com>
6 *
7 * This file is part of messaging-app.
8 *
9 * messaging-app is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * messaging-app is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22import QtQuick 2.2
23import QtTest 1.0
24import Ubuntu.Test 0.1
25
26import '../../src/qml/MMS'
27
28Item {
29 id: root
30
31 width: units.gu(40)
32 height: units.gu(40)
33
34 PreviewerImage {
35 id: previewerImage
36 objectName: "previewerImage"
37
38 property var application: QtObject {
39 property bool fullscreen: false
40 }
41
42 anchors.fill: parent
43
44 attachment: {
45 "contentType": "image/png",
46 "filePath": Qt.resolvedUrl("./data/sample.png")
47 }
48 }
49
50 UbuntuTestCase {
51 id: previewerImageTestCase
52 name: 'peviewerImageTestCase'
53
54 when: windowShown
55
56 function test_load_image() {
57 var activityIndicator = findChild(previewerImage, "imageActivityIndicator")
58 verify(activityIndicator != null)
59 tryCompare(activityIndicator, "visible", false)
60
61 var thumbnail = findChild(previewerImage, "thumbnailImage")
62 verify(thumbnail != null)
63 tryCompare(thumbnail, "opacity", 1.0)
64
65 var highRes = findChild(previewerImage, "highResolutionImage")
66 verify(highRes != null)
67 compare(highRes.source, "")
68 }
69
70 function test_zoom_in_out() {
71 var activityIndicator = findChild(previewerImage, "imageActivityIndicator")
72 verify(activityIndicator != null)
73 tryCompare(activityIndicator, "visible", false)
74
75 var thumbnail = findChild(previewerImage, "thumbnailImage")
76 verify(thumbnail != null)
77 tryCompare(thumbnail, "opacity", 1.0)
78
79 var highRes = findChild(previewerImage, "highResolutionImage")
80 verify(highRes != null)
81 compare(highRes.source, "")
82
83 mouseDoubleClick(thumbnail)
84 verify(highRes.source !== "")
85
86 mouseDoubleClick(thumbnail)
87 compare(highRes.source, "")
88 }
89
90 function test_toggle_fullscreen() {
91 var activityIndicator = findChild(previewerImage, "imageActivityIndicator")
92 verify(activityIndicator != null)
93 tryCompare(activityIndicator, "visible", false)
94
95 var thumbnail = findChild(previewerImage, "thumbnailImage")
96 verify(thumbnail != null)
97
98 verify(previewerImage.application.fullscreen)
99 mouseClick(thumbnail)
100 tryCompare(previewerImage.application, "fullscreen", false)
101 }
102 }
103}
0104
=== added file 'tests/qml/tst_PreviewerVideo.qml'
--- tests/qml/tst_PreviewerVideo.qml 1970-01-01 00:00:00 +0000
+++ tests/qml/tst_PreviewerVideo.qml 2015-12-08 18:33:04 +0000
@@ -0,0 +1,87 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * Authors:
5 * Arthur Mello <arthur.mello@canonical.com>
6 *
7 * This file is part of messaging-app.
8 *
9 * messaging-app is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * messaging-app is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22import QtQuick 2.2
23import QtTest 1.0
24import Ubuntu.Content 0.1
25import Ubuntu.Test 0.1
26
27import '../../src/qml/MMS'
28
29Item {
30 id: root
31
32 width: units.gu(40)
33 height: units.gu(40)
34
35 PreviewerVideo {
36 id: previewerVideo
37 objectName: "previewerVideo"
38
39 property var application: QtObject {
40 property bool fullscreen: false
41 }
42
43 function getContentType(filePath) {
44 return ContentType.Videos
45 }
46
47 anchors.fill: parent
48
49 attachment: {
50 "contentType": "video/mp4",
51 "filePath": Qt.resolvedUrl("./data/sample.mp4")
52 }
53 }
54
55 UbuntuTestCase {
56 id: previewerVideoTestCase
57 name: 'peviewerVideoTestCase'
58
59 when: windowShown
60
61 function test_load_video() {
62 var videoPlayer = findChild(previewerVideo, "videoPlayer")
63 verify(videoPlayer != null)
64 tryCompare(videoPlayer, "visible", true)
65
66 var toolbar = findChild(previewerVideo, "toolbar")
67 verify(toolbar != null)
68 tryCompare(toolbar, "collapsed", true)
69 }
70
71 function test_toggle_toolbar() {
72 var videoPlayer = findChild(previewerVideo, "videoPlayer")
73 verify(videoPlayer != null)
74 tryCompare(videoPlayer, "visible", true)
75
76 var toolbar = findChild(previewerVideo, "toolbar")
77 verify(toolbar != null)
78 tryCompare(toolbar, "collapsed", true)
79
80 mouseClick(videoPlayer)
81 tryCompare(toolbar, "collapsed", false)
82
83 mouseClick(videoPlayer)
84 tryCompare(toolbar, "collapsed", true)
85 }
86 }
87}
088
=== added file 'tests/qml/tst_QmlTests.cpp'
--- tests/qml/tst_QmlTests.cpp 1970-01-01 00:00:00 +0000
+++ tests/qml/tst_QmlTests.cpp 2015-12-08 18:33:04 +0000
@@ -0,0 +1,61 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * Authors:
5 * Arthur Mello <arthur.mello@canonical.com>
6 *
7 * This file is part of messaging-app.
8 *
9 * messaging-app is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * messaging-app is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22// Qt
23#include <QtQuickTest/QtQuickTest>
24#include <QtQml/QtQml>
25
26// local
27#include "fileoperations.h"
28
29class TestContext : public QObject
30{
31 Q_OBJECT
32
33public:
34 explicit TestContext(QObject* parent=0)
35 : QObject(parent)
36 {}
37};
38
39static QObject* TestContext_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine)
40{
41 Q_UNUSED(engine);
42 Q_UNUSED(scriptEngine);
43 return new TestContext();
44}
45
46static QObject* FileOperations_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine)
47{
48 Q_UNUSED(engine);
49 Q_UNUSED(scriptEngine);
50 return new FileOperations();
51}
52
53int main(int argc, char** argv)
54{
55 qmlRegisterSingletonType<FileOperations>("messagingapp.private", 0, 1, "FileOperations", FileOperations_singleton_factory);
56 qmlRegisterSingletonType<TestContext>("messagingtest.private", 0, 1, "TestContext", TestContext_singleton_factory);
57
58 return quick_test_main(argc, argv, "QmlTests", 0);
59}
60
61#include "tst_QmlTests.moc"

Subscribers

People subscribed via source and target branches