on xenial help sign in
Cleanup a very large mess.
commit64f454920f227294c3d0d27c391dc45c3991495b authorJosh Arenson <joshua.arenson@canonical.com> dateTue 1 Mar 2016, 18:37 (11 years ago) parent8c9dfb5f77a0fe
328 files changed+7310−1751
CMakeLists.txt+14−1 data/51-unity8-greeter.conf+3 data/CMakeLists.txt+1−1 data/unity8-greeter-init.conf+12 data/unity8-greeter-wrapper+98 data/unity8-greeter.desktop.in+2−1 data/unity8.conf+4−2 debian/changelog+230 debian/control+12−8 debian/rules−4 debian/tests/autopilot.sh+13 debian/tests/control+5 debian/tests/qmluitests.sh+4−2 debian/unity8-greeter.install+2 debian/unity8-private.install+1 plugins/AccountsService/AccountsService.cpp+61 plugins/AccountsService/AccountsService.h+4 plugins/CMakeLists.txt+1 plugins/Cursor/MousePointer.cpp+4 plugins/Cursor/MousePointer.h+1 plugins/Dash/AudioProgressBar.qml+53 plugins/Dash/CMakeLists.txt+3 plugins/Dash/CardAudioProgress.qml+59 plugins/Dash/CardCreator.js+186−28 plugins/Dash/CardCreatorCache.qml+1−1 plugins/Dash/DashAudioPlayer.qml+96 plugins/Dash/graphics/music_progress_bg.png plugins/Dash/listviewwithpageheader.cpp+23−10 plugins/Dash/listviewwithpageheader.h+1 plugins/Dash/plugin.cpp+35 plugins/Dash/qmldir+3 plugins/LightDM/CMakeLists.txt+2 plugins/LightDM/FullLightDM/CMakeLists.txt+1−7 plugins/LightDM/FullLightDM/qmldir+3 plugins/LightDM/IntegratedLightDM/CMakeLists.txt+5−5 plugins/LightDM/IntegratedLightDM/liblightdm/CMakeLists.txt+3 plugins/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+23−7 plugins/LightDM/IntegratedLightDM/qmldir+3 plugins/LightDM/qmldir.in−3 plugins/Powerd/CMakeLists.txt−2 plugins/UInput/CMakeLists.txt+7 plugins/UInput/UInput.qmltypes+44 plugins/UInput/plugin.cpp+26 plugins/UInput/plugin.h+32 plugins/UInput/qmldir+3 plugins/UInput/uinput.cpp+182 plugins/UInput/uinput.h+61 plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+8−2 plugins/Unity/DashCommunicator/dashcommunicator.cpp+6 plugins/Unity/DashCommunicator/dashcommunicator.h+1−1 plugins/Unity/Indicators/CMakeLists.txt−4 plugins/Unity/Indicators/modelactionrootstate.cpp+76−1 plugins/Unity/Indicators/modelactionrootstate.h+15−4 plugins/Unity/Session/CMakeLists.txt−2 plugins/Utils/CMakeLists.txt+2−3 plugins/Utils/EdgeBarrierSettings.qml+1−1 plugins/Utils/HomeKeyWatcher.h−74 plugins/Utils/HomeKeyWatcher.cpp → plugins/Utils/WindowInputMonitor.cpp+19−12 plugins/Utils/WindowInputMonitor.h+91 plugins/Utils/inputeventgenerator.cpp+34 plugins/Utils/inputeventgenerator.h+40 plugins/Utils/plugin.cpp+4−2 po/aa.po+667 po/am.po+21−4 po/ar.po+7−7 po/ast.po+19−18 po/az.po+4−3 po/be.po+10−10 po/bg.po+6−5 po/bn.po+163−100 po/br.po+38−19 po/bs.po+6−5 po/ca.po+20−13 po/ca@valencia.po+9−8 po/ce.po+4−3 po/ckb.po+4−3 po/cs.po+8−10 po/cy.po+6−5 po/da.po+8−6 po/de.po+23−7 po/el.po+5−5 po/en_AU.po+23−15 po/en_GB.po+26−9 po/eo.po+44−43 po/es.po+26−7 po/eu.po+6−5 po/fa.po+10−13 po/fi.po+21−5 po/fo.po+4−3 po/fr.po+29−8 po/ga.po+137−120 po/gd.po+36−15 po/gl.po+24−6 po/gv.po+9−7 po/he.po+6−5 po/hi.po+4−3 po/hr.po+25−7 po/hu.po+23−6 po/hy.po+4−3 po/ia.po+16−15 po/id.po+4−3 po/is.po+8−7 po/it.po+14−11 po/ja.po+23−15 po/km.po+10−14 po/kn.po+4−3 po/ko.po+36−18 po/ku.po+6−4 po/ky.po+4−3 po/lo.po+4−3 po/lt.po+8−6 po/lv.po+4−4 po/ml.po+5−5 po/mr.po+4−3 po/ms.po+8−8 po/my.po+4−3 po/nb.po+16−13 po/ne.po+4−3 po/nl.po+8−6 po/nn.po+4−3 po/oc.po+4−3 po/or.po+4−3 po/pa.po+13−15 po/pl.po+26−7 po/pt.po+31−13 po/pt_BR.po+4−3 po/ro.po+6−7 po/ru.po+11−10 po/shn.po+18−18 po/si.po+4−3 po/sk.po+4−3 po/sl.po+58−18 po/sq.po+4−3 po/sr.po+14−7 po/sv.po+24−19 po/sw.po+4−3 po/ta.po+4−4 po/te.po+4−3 po/th.po+4−3 po/tr.po+4−3 po/ug.po+6−5 po/uk.po+26−8 po/unity8.pot+40−38 po/ur.po+4−3 po/uz.po+4−3 po/vi.po+4−3 po/wo.po+7−7 po/xh.po+4−3 po/zh_CN.po+27−7 po/zh_HK.po+4−3 po/zh_TW.po+23−12 qml/Components/EdgeBarrierController.qml+2 qml/Components/InputMethod.qml+1−1 qml/Components/PhysicalKeysMapper.qml+32−2 qml/Components/ResponsiveGridView.qml+2−4 qml/Components/VirtualTouchPad.qml+138 qml/Components/VolumeControl.qml+1−6 qml/Components/ZoomableImage.qml+1−1 qml/Dash/CardCarousel.qml−1 qml/Dash/CardGrid.qml+3−2 qml/Dash/CardHorizontalList.qml−1 qml/Dash/CardTool.qml−1 qml/Dash/CardVerticalJournal.qml−1 qml/Dash/DashBackground.qml+6−2 qml/Dash/DashPageHeader.qml+1 qml/Dash/GenericScopeView.qml+20−9 qml/Dash/Previews/PreviewAudioPlayback.qml+21−76 qml/Dash/Previews/PreviewHeader.qml+1−1 qml/Dash/Previews/PreviewImageGallery.qml+2−2 qml/Dash/Previews/PreviewMediaToolbar.qml+2−1 qml/Dash/Previews/PreviewRatingEdit.qml+1 qml/Dash/Previews/PreviewSharing.qml+3−4 qml/Dash/Previews/PreviewVideoPlayback.qml+1−1 qml/Dash/Previews/PreviewZoomableImage.qml+3−3 qml/Dash/Previews/graphics/music_progress_bg.png qml/Dash/graphics/paper.png qml/Dash/graphics/paper_landscape@27.png qml/Dash/graphics/paper_portrait@27.png qml/DisabledScreenNotice.qml+72−19 qml/Greeter/Greeter.qml+9−5 qml/Greeter/LoginList.qml+5 qml/Greeter/WideView.qml+3−1 qml/Launcher/Launcher.qml+22−28 qml/Launcher/LauncherPanel.qml+6−3 qml/OrientedShell.qml+28−14 qml/Panel/IndicatorItem.qml+57−7 qml/Panel/Indicators/MenuItemFactory.qml+24−2 qml/Panel/graphics/Battery@18.png qml/Panel/graphics/Bluetooth@18.png qml/Panel/graphics/Clock@18.png qml/Panel/graphics/Location@18.png qml/Panel/graphics/Messages@18.png qml/Panel/graphics/Network@18.png qml/Panel/graphics/Sound@18.png qml/Panel/graphics/Sync@18.png qml/Panel/graphics/System@18.png qml/Panel/graphics/Time@18.png qml/Panel/graphics/VerticalDivider@18.png qml/Panel/graphics/handle@12.png qml/Panel/graphics/handle@12.sci−5 qml/Panel/graphics/search@12.png qml/Panel/graphics/time_and_date@18.png qml/Shell.qml+15−6 qml/Stages/AbstractStage.qml+5−1 qml/Stages/ApplicationWindow.qml+14−1 qml/Stages/DecoratedWindow.qml+7 qml/Stages/DesktopStage.qml+19−4 qml/Stages/PhoneStage.qml+5−1 qml/Stages/SessionContainer.qml+2 qml/Stages/Splash.qml+7−2 qml/Stages/TabletStage.qml+5−1 qml/Stages/WindowResizeArea.qml+95−16 qml/Wizard/Pages/10-welcome.qml+1−1 qml/Wizard/Pages/30-passwd-type.qml+6−1 qml/Wizard/Pages/80-finished.qml+1−1 src/CMakeLists.txt+13−7 src/Dash/CMakeLists.txt+8−8 src/Dash/main.cpp+9−5 src/MouseTouchAdaptor.cpp+180−21 src/MouseTouchAdaptor.h+10−3 src/ShellApplication.cpp+10−5 src/ShellApplication.h+12−4 src/UnityCommandLineParser.cpp+6 src/UnityCommandLineParser.h+8 tests/mocks/CMakeLists.txt+1 tests/mocks/Cursor/Cursor.qml+1 tests/mocks/QtMultimedia/CMakeLists.txt+1 tests/mocks/QtMultimedia/audio.cpp+21−19 tests/mocks/QtMultimedia/audio.h+8−6 tests/mocks/QtMultimedia/declarativeplaylist.cpp+73 tests/mocks/QtMultimedia/declarativeplaylist.h+54 tests/mocks/QtMultimedia/plugin.cpp+2 tests/mocks/UInput/CMakeLists.txt+7 tests/mocks/UInput/mockuinput.cpp+73 tests/mocks/UInput/mockuinput.h+63 tests/mocks/UInput/plugin.cpp+26 tests/mocks/UInput/plugin.h+32 tests/mocks/UInput/qmldir+2 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/CMakeLists.txt+1−1 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.cpp+8−1 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.h+8 tests/mocks/Unity/Application/ApplicationInfo.cpp+14−1 tests/mocks/Unity/Application/ApplicationInfo.h+4−1 tests/mocks/Unity/Application/ApplicationTestInterface.cpp+4−4 tests/mocks/Unity/Application/ApplicationTestInterface.h+2−2 tests/mocks/Unity/Application/MirSurface.cpp+48 tests/mocks/Unity/Application/MirSurface.h+21 tests/mocks/Unity/Application/MirSurfaceItem.cpp+6 tests/mocks/Unity/Application/MirSurfaceItem.h+14 tests/mocks/Unity/Application/SurfaceManager.cpp+56 tests/mocks/Unity/Application/SurfaceManager.h+40 tests/mocks/Unity/CMakeLists.txt+2−1 tests/mocks/Unity/Indicators/ModelActionRootState.qml+11−1 tests/mocks/Unity/Screens/CMakeLists.txt+14 tests/mocks/Unity/Screens/plugin.cpp+29 tests/mocks/Unity/Screens/plugin.h+25 tests/mocks/Unity/Screens/qmldir+2 tests/mocks/Unity/Screens/screens.cpp+71 tests/mocks/Unity/Screens/screens.h+82 tests/mocks/Unity/fake_categories.cpp+1−1 tests/mocks/Utils/CMakeLists.txt+1−2 tests/mocks/Utils/HomeKeyWatcher.qml → tests/mocks/Utils/WindowInputMonitor.qml+3−1 tests/mocks/Utils/plugin.cpp+2 tests/mocks/Utils/qmldir+1−1 tests/mocks/indicator-service/CMakeLists.txt−1 tests/plugins/Dash/cardcreator/1.res+6−7 tests/plugins/Dash/cardcreator/10.res+141 tests/plugins/Dash/cardcreator/10.tst+3 tests/plugins/Dash/cardcreator/11.res+216 tests/plugins/Dash/cardcreator/11.tst+3 tests/plugins/Dash/cardcreator/2.res−1 tests/plugins/Dash/cardcreator/3.res+7−7 tests/plugins/Dash/cardcreator/3.tst+1−1 tests/plugins/Dash/cardcreator/4.res−1 tests/plugins/Dash/cardcreator/5.res+6−7 tests/plugins/Dash/cardcreator/5.tst+1−1 tests/plugins/Dash/cardcreator/6.res+1−2 tests/plugins/Dash/cardcreator/7.res−1 tests/plugins/Dash/cardcreator/8.res+1−2 tests/plugins/Dash/cardcreator/9.res+121 tests/plugins/Dash/cardcreator/9.tst+3 tests/plugins/Dash/cardcreatortest.cpp+1 tests/plugins/Dash/listviewwithpageheadertest.cpp+23 tests/plugins/Dash/listviewwithpageheadertest.qml−1 tests/plugins/Unity/Indicators/CMakeLists.txt−4 tests/plugins/Unity/Launcher/launchermodeltest.cpp+2 tests/plugins/Unity/Session/sessionbackendtest.cpp+1 tests/plugins/Utils/CMakeLists.txt+1−1 tests/plugins/Utils/HomeKeyWatcherTest.cpp → tests/plugins/Utils/WindowInputMonitorTest.cpp+14−14 tests/qmltests/CMakeLists.txt+4−2 tests/qmltests/Components/CMakeLists.txt+1−1 tests/qmltests/Components/tst_DragHandle.qml+6−6 tests/qmltests/Components/tst_DragHandle/SimpleButton.qml+36 tests/qmltests/Components/tst_LazyImage.qml+27−8 tests/qmltests/Components/tst_PhysicalKeysMapper.qml+136−62 tests/qmltests/Components/tst_ResponsiveGridView.qml−36 tests/qmltests/Components/tst_VirtualTouchPad.qml+143 tests/qmltests/Components/tst_ZoomableImage.qml+8−5 tests/qmltests/Dash/CardHelpers.js+1−1 tests/qmltests/Dash/Previews/tst_Preview.qml+5−6 tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+16−11 tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+15 tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+19 tests/qmltests/Dash/Previews/tst_PreviewMediaToolbar.qml+69 tests/qmltests/Dash/Previews/tst_PreviewSharing.qml+1−13 tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+12 tests/qmltests/Dash/tst_Card.qml+30−7 tests/qmltests/Dash/tst_CardBenchmark.qml−2 tests/qmltests/Dash/tst_DashContent.qml+1−1 tests/qmltests/Dash/tst_GenericScopeView.qml+30−9 tests/qmltests/Greeter/tst_Greeter.qml+39−3 tests/qmltests/Greeter/tst_WideView.qml+11 tests/qmltests/Launcher/tst_Launcher.qml+42 tests/qmltests/Panel/tst_IndicatorsMenu.qml+3−3 tests/qmltests/Stages/RecursingChildSessionControl.qml+3−3 tests/qmltests/Stages/SizeHintField.qml+33 tests/qmltests/Stages/SurfaceManagerControls.qml+33 tests/qmltests/Stages/SurfaceManagerField.qml+40 tests/qmltests/Stages/tst_DesktopStage.qml+59−24 tests/qmltests/Stages/tst_SessionContainer.qml+27−5 tests/qmltests/Stages/tst_WindowResizeArea.qml+225−30 tests/qmltests/Wizard/tst_Wizard.qml+15 tests/qmltests/tst_DisabledScreenNotice.qml+10−2 tests/qmltests/tst_OrientedShell.qml+107−23 tests/qmltests/tst_Shell.qml+75−6 tests/qmltests/tst_ShellWithPin.qml+19−5 tests/utils/modules/Unity/Test/CMakeLists.txt+8−1 tests/utils/modules/Unity/Test/plugin.cpp+13−3
CMakeLists.txt+14−1
@@ -57,7 +57,10 @@ find_package(Qt5DBus 5.4 REQUIRED)
5757find_package(Qt5Concurrent 5.4 REQUIRED)
5858find_package(Qt5Sql 5.4 REQUIRED)
5959
60−pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=12)
60+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=13)
61+pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
62+pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
63+pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
6164
6265# Standard install paths
6366include(GNUInstallDirs)
@@ -129,6 +132,16 @@ if(NOT QUIET_LOGGER)
129132 set(STDOUT_LOGGER "-o" "-,txt")
130133endif()
131134
135+execute_process(COMMAND arch OUTPUT_VARIABLE ARCH)
136+if (NOT ARCH MATCHES "arm*")
137+ set(ENABLE_TOUCH_EMULATION true)
138+ add_definitions(-DUNITY8_ENABLE_TOUCH_EMULATION)
139+ pkg_check_modules(MOUSETOUCHADAPTOR_LIBS REQUIRED x11 xcb xi)
140+else()
141+ set(ENABLE_TOUCH_EMULATION false)
142+ message(STATUS "Touch emulation support disabled.")
143+endif()
144+
132145# add subdirectories to build
133146add_subdirectory(include)
134147add_subdirectory(libs)
data/51-unity8-greeter.conf+3
@@ -1,2 +1,5 @@
11[Seat:*]
22greeter-session=unity8-greeter
3+
4+# When unity8 can be run under mir on the desktop, change this to unity.
5+type=xlocal
data/CMakeLists.txt+1−1
@@ -22,7 +22,7 @@ install(FILES
2222 DESTINATION ${CMAKE_INSTALL_DATADIR}/lightdm/lightdm.conf.d
2323 )
2424
25− # install dash icon
25+# install dash icon
2626install(FILES
2727 ${CMAKE_CURRENT_SOURCE_DIR}/${DASH_APP}.png
2828 DESTINATION ${SHELL_APP_DIR}/Dash/
data/unity8-greeter-init.confnew file+12
@@ -0,0 +1,12 @@
1+description "Unity 8 Greeter initialization"
2+author "Michael Terry <mterry@ubuntu.com>"
3+
4+start on unity8-greeter-started
5+task
6+emits indicator-services-start
7+
8+script
9+ start --no-wait ofono-setup || true
10+ initctl emit --no-wait indicator-services-start || true
11+ start --no-wait maliit-server || true
12+end script
data/unity8-greeter-wrappernew file+98
@@ -0,0 +1,98 @@
1+#!/bin/sh
2+# -*- Mode: sh; indent-tabs-mode: nil; tab-width: 4 -*-
3+#
4+# Copyright (C) 2011,2013 Canonical Ltd
5+# Author: Michael Terry <michael.terry@canonical.com>
6+#
7+# This program is free software: you can redistribute it and/or modify it under
8+# the terms of the GNU General Public License as published by the Free Software
9+# Foundation, version 3 of the License.
10+#
11+# See http://www.gnu.org/copyleft/gpl.html the full text of the license.
12+
13+# This wrapper merely ensures that init and friends live only as long as this
14+# script does. Otherwise, it's very easy for some processes to not notice that
15+# the session died. We could try to do this in-process, but we want to do this
16+# cleanup even if the greeter aborts.
17+
18+trap cleanup TERM EXIT
19+
20+cleanup()
21+{
22+ trap - TERM EXIT
23+ # Kill upstart and indicators
24+ if [ -n "$INIT_PID" ]; then
25+ kill "$INIT_PID"
26+ fi
27+ if [ -n "$CMD_PID" ]; then
28+ kill "$CMD_PID"
29+ fi
30+ exit 0
31+}
32+
33+set_greeter_var()
34+{
35+ export "$1=$2"
36+ gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "{'$1': '$2'}"
37+ if [ -n "$INIT_PID" ]; then
38+ initctl set-env --global "$1=$2"
39+ fi
40+}
41+
42+SUB_SOCKET=$XDG_RUNTIME_DIR/mir_socket
43+rm -f $SUB_SOCKET # clear socket in case we were hard shut down
44+
45+# If touch session script (which sets up grid units and mir variables) is available, use it
46+TOUCH_WRAPPER=
47+if [ -x /usr/bin/ubuntu-touch-session ]; then
48+ TOUCH_WRAPPER=/usr/bin/ubuntu-touch-session
49+fi
50+
51+# Pretend that we're in an ubuntu-touch session, so that indicator-network
52+# will start.
53+export DESKTOP_SESSION=ubuntu-touch
54+
55+# We disable ofono using pulse. It causes problems with racing with the user's
56+# pulse. We need to come up with a better long-term fix for this, because we
57+# eventually need the greeter to play ringtones for users that aren't logged in.
58+set_greeter_var PA_DISABLED 1
59+
60+# Normal unity8 sessions are entirely driven by Upstart. But greeters
61+# are special. They need access to the file descriptors that lightdm
62+# creates for them and don't want to start all the services that a normal
63+# session would. So it's inconvenient to live within an upstart session.
64+# But... we still want to use Upstart for some services. So launch here.
65+USC_SOCKET=$MIR_SOCKET MIR_SOCKET=$SUB_SOCKET $TOUCH_WRAPPER /sbin/upstart --user --no-startup-event &
66+INIT_PID=$!
67+while [ ! -e "$XDG_RUNTIME_DIR/upstart/sessions/$INIT_PID.session" ]; do sleep 0.1; done
68+export UPSTART_SESSION=$(/sbin/initctl list-sessions | grep "^$INIT_PID " | cut -d' ' -f2)
69+
70+# Start any pre-greeter tasks if needed (like wizard)
71+/sbin/initctl emit unity8-greeter-starting
72+
73+# Define language here for phone if available. When phone user switches their
74+# language, they expect that to affect the greeter too. But the user doesn't
75+# have permission to switch system language, only their own. So we notice if
76+# the phablet user exists and use their language if so. TODO: talk to design
77+# about whether we should switch language on fly as users are selected (this
78+# is very hard to do technically).
79+#
80+# Do this after unity8-greeter-starting, in case a customization upstart job
81+# changes language.
82+if [ "$(id -u phablet 2>/dev/null)" = "32011" ]; then
83+ USER_LANG=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User Language | cut -d\' -f2)
84+ if [ -n "$USER_LANG" ]; then
85+ set_greeter_var LANGUAGE "$USER_LANG"
86+ fi
87+ USER_LOCALE=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User FormatsLocale | cut -d\' -f2)
88+ if [ -n "$USER_LOCALE" ]; then
89+ set_greeter_var LANG "$USER_LOCALE"
90+ set_greeter_var LC_ALL "$USER_LOCALE"
91+ fi
92+fi
93+
94+# And finally actually start the greeter
95+exec env QT_QPA_PLATFORM=ubuntumirclient MIR_SERVER_FILE=$SUB_SOCKET $TOUCH_WRAPPER $@ &
96+CMD_PID=$!
97+wait $CMD_PID
98+CMD_PID=
data/unity8-greeter.desktop.in+2−1
@@ -2,5 +2,6 @@
22Type=Application
33Name=Unity 8 Greeter
44Comment=The converged Unity shell's Greeter
5−Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8 --mode=greeter
5+Exec=/usr/bin/unity8-greeter-wrapper /usr/bin/unity8 --mode=greeter
6+X-LightDM-Session-Type=mir
67X-Ubuntu-Touch=true
data/unity8.conf+4−2
@@ -44,7 +44,11 @@ pre-start script
4444 fi
4545
4646 initctl set-env --global MIR_SERVER_PROMPT_FILE=1
47+end script
48+
49+exec ${BINARY:-unity8} $ARGS
4750
51+post-start script
4852 initctl emit --no-wait indicator-services-start
4953
5054 # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
@@ -58,8 +62,6 @@ pre-start script
5862 # initctl set-env MIR_SERVER_NBUFFERS=2
5963end script
6064
61−exec ${BINARY:-unity8} $ARGS
62−
6365post-stop script
6466 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
6567 initctl unset-env --global UNITY_MIR_SOCKET
debian/changelog+230
@@ -1,3 +1,233 @@
1+unity8 (8.11+16.04.20160216.1-0ubuntu1) xenial; urgency=medium
2+
3+ [ Albert Astals Cid ]
4+ * Make the audio previews create a playlist (LP: #1540477)
5+
6+ [ CI Train Bot ]
7+ * Resync trunk. added: po/aa.po
8+ * Update translation template
9+
10+ -- Pawel Stolowski <ci-train-bot@canonical.com> Tue, 16 Feb 2016 03:24:46 +0000
11+
12+unity8 (8.11+16.04.20160212-0ubuntu1) xenial; urgency=medium
13+
14+ [ Albert Astals Cid ]
15+ * Do not use components in card creator generated code
16+ * Forward the makesurevisible signal from the inner preview widget
17+ * Make fallback also be fallback when the image is empty and not only
18+ on error (LP: #1531913)
19+ * Make the artShapeSize assignment be updated when using dynamic grid
20+ units
21+ * Visual improvements to the dash audio play cards
22+ * We don't use the unity-scope-scopes anymore (LP: #1439172)
23+
24+ [ Andrea Cimitan ]
25+ * only request a bigger image if zoomable widget data property is
26+ true, otherwise just leave the screen size (LP: #1536814)
27+
28+ [ CI Train Bot ]
29+ * Update translation template
30+
31+ [ Daniel d'Andrada ]
32+ * Set initial surface size (LP: #1532974)
33+
34+ [ Daniel d'Andrada, Michał Sawicz ]
35+ * Window Size Hints
36+
37+ [ Florian Boucault ]
38+ * Splash screen: delay showing the ActivityIndicator by 2 seconds.
39+
40+ [ Lukáš Tinkl ]
41+ * Replace the word "phone" with a more generic term "device" in the
42+ welcome wizard (LP: #1294732, #1543527)
43+
44+ [ Michael Terry ]
45+ * Have the tablet greeter set appropriate OSK hints if the user has a
46+ passcode instead of a passphrase. (LP: #1544173)
47+
48+ [ Michael Zanetti ]
49+ * Don't eat mouse events in the edgebarrer
50+
51+ [ Michał Sawicz ]
52+ * Bump unity-api dependencies
53+
54+ [ Nick Dedekind ]
55+ * Added support for secondary indicator actions (LP: #1398888)
56+ * Remove zombie if they're not animated. (LP: #1534541)
57+ * Removed unused panel resources
58+
59+ [ Ted Gould ]
60+ * Start the indicators after Unity8 starts instead of before
61+
62+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 12 Feb 2016 00:12:41 +0000
63+
64+unity8 (8.11+16.04.20160208-0ubuntu1) xenial; urgency=medium
65+
66+ [ Albert Astals Cid ]
67+ * LVWPH: Reset to initial values when list is empty (LP: #1540490)
68+ * Make LazyImage qmltest less flaky on CI
69+
70+ [ Andrea Cimitan ]
71+ * Make LazyImage qmltest less flaky on CI
72+
73+ [ CI Train Bot ]
74+ * Resync trunk.
75+ * Update translation template
76+
77+ [ Michael Terry ]
78+ * Display the current user's real name on the tablet lockscreen. (LP:
79+ #1536714)
80+
81+ -- Michał Sawicz <michal.sawicz@canonical.com> Mon, 08 Feb 2016 09:38:00 +0000
82+
83+unity8 (8.11+16.04.20160129-0ubuntu1) xenial; urgency=medium
84+
85+ [ Albert Astals Cid ]
86+ * Audio Preview Button: Don't gain focus on press (LP: #1517830)
87+ * Better attempt at sanitization
88+ * Better looking application scopes for wide screens
89+ * Call printSettings correctly
90+ * Card test: Limit the precision we ask for doubles to be equal
91+ * Convert while into tryCompareFunction
92+ * Do not use the same filepath parameter for all the card creator
93+ createQmlObject calls (LP: #1536379)
94+ * Fix some test shells being unstable in the armhf builders
95+ * Make revealByEdgePush more stable
96+ * More reliable compares
97+ * Move the mouse over the bfb before waiting for rendering
98+ * Remove the DDAs constrains for every test
99+ * Set the background source size to the max we'll need + new
100+ background (LP: #1539011)
101+
102+ [ Andrea Cimitan ]
103+ * Dynamically change click scope card size according to size (LP:
104+ #1536745)
105+ * Should fix lazyimage test failures on fast machines
106+
107+ [ CI Train Bot ]
108+ * Fix card tests on the phone
109+ * Update translation template
110+
111+ [ Daniel d'Andrada ]
112+ * Desktop stage rotates only to follow screen orientation (LP:
113+ #1515977)
114+
115+ [ Lukáš Tinkl ]
116+ * Hide/reveal the mouse pointer on touch/mouse events renamed:
117+ plugins/Utils/HomeKeyWatcher.cpp =>
118+ plugins/Utils/WindowInputMonitor.cpp plugins/Utils/HomeKeyWatcher.h
119+ => plugins/Utils/WindowInputMonitor.h
120+ tests/mocks/Utils/HomeKeyWatcher.qml =>
121+ tests/mocks/Utils/WindowInputMonitor.qml
122+ tests/plugins/Utils/HomeKeyWatcherTest.cpp =>
123+ tests/plugins/Utils/WindowInputMonitorTest.cpp
124+
125+ [ Michael Terry ]
126+ * Synchronize the mouse-cursor-speed and touchpad-cursor-speed
127+ properties with USC. (LP: #1536383)
128+
129+ [ Michael Zanetti ]
130+ * Add InputMethod to secondary screen
131+ * Add a virtual Touchpad while external screen is connected
132+ * Make big tablets switch to windowed mode by plugging a kbd only (LP:
133+ #1535399)
134+ * Prevent alt key presses from being dispatched to the app on alt+tab
135+ (LP: #1532862)
136+
137+ [ Michał Sawicz ]
138+ * Make qmluitests.sh more robust and allow parallel test execution
139+ * Skip SessionBackendTest::testLogin1Capabilities until we talk to a
140+ mock instead (LP: #1532112, #1532113)
141+
142+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 29 Jan 2016 11:53:27 +0000
143+
144+unity8 (8.11+16.04.20160122-0ubuntu1) xenial; urgency=medium
145+
146+ [ Albert Astals Cid ]
147+ * Fix bug #1536296 added: tests/plugins/Dash/cardcreator/10.tst (LP:
148+ #1536296)
149+ * Fix card tests on the phone
150+
151+ [ CI Train Bot ]
152+ * Update translation template
153+
154+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 22 Jan 2016 16:56:04 +0000
155+
156+unity8 (8.11+16.04.20160111.1-0ubuntu1) xenial; urgency=medium
157+
158+ [ Albert Astals Cid ]
159+ * Clear fake item icon name as soon as it goes invisible (LP:
160+ #1531172)
161+ * Fix LVWPH test failing on Xenial (Qt 5.5)
162+ * Fix dragging so that test passes on Xenial
163+ * Fix focus on the dash page header text field with new SDK (LP:
164+ #1528178)
165+ * Make the card creator test pass again
166+ * Quit the dash communicator thread before destroying it (LP:
167+ #1508485)
168+ * Remove duplicated override_dh_auto_clean
169+ * SDK changed the name they give to the buttons, follow
170+
171+ [ Andrea Cimitan ]
172+ * Fix a broken binding
173+
174+ [ CI Train Bot ]
175+ * Resync trunk.
176+ * Update translation template
177+
178+ [ Daniel d'Andrada ]
179+ * Have "make tryFoo" work with Qt 5.5
180+ * Make DragHandle tests run again.
181+
182+ [ Lukáš Tinkl ]
183+ * Fix dismissing the launcher when clicking/tapping outside (LP:
184+ #1531339, #1530940)
185+ * Fix panel drop shadow and click-to-focus of maximized apps (LP:
186+ #1531854)
187+ * Fix wifi access point indicator items signal strength icon on
188+ desktop
189+
190+ [ Michael Terry ]
191+ * Guard against a couple odd timing scenarios for the too-many-failed-
192+ login-attempts lockout screen.
193+ * Skip the wizard's password screens if there is already a password
194+ set by other means. (LP: #1531268)
195+ * Stop the emergency dialer from accidentally exposing the mtp
196+ service. (LP: #1525981)
197+
198+ [ Michael Zanetti ]
199+ * Make sure the triangle of the quicklist is in bounds (LP: #1531340)
200+
201+ [ Pawel Stolowski ]
202+ * Changes 'shareData' and 'contentType' attributes to 'share-data' and
203+ 'content-type', to match existing naming schema.
204+
205+ -- Michał Sawicz <michal.sawicz@canonical.com> Mon, 11 Jan 2016 17:38:49 +0000
206+
207+unity8 (8.11+16.04.20160107-0ubuntu1) xenial; urgency=medium
208+
209+ [ Albert Astals Cid ]
210+ * Introduce audio cards
211+
212+ [ CI Train Bot ]
213+ * Update translation template
214+
215+ [ Michael Zanetti ]
216+ * Introduce audio cards
217+
218+ -- CI Train Bot <ci-train-bot@canonical.com> Thu, 07 Jan 2016 08:04:47 +0000
219+
220+unity8 (8.11+16.04.20160105.1-0ubuntu1) xenial; urgency=medium
221+
222+ [ CI Train Bot ]
223+ * Resync trunk.
224+ * Update translation template
225+
226+ [ Nick Dedekind ]
227+ * Use volume-sync action to resync the volume control. (LP: #1520548)
228+
229+ -- Xavi Garcia <xavi.garcia.mena@canonical.com> Tue, 05 Jan 2016 13:55:38 +0000
230+
1231unity8 (8.11+16.04.20151208.1-0ubuntu1) xenial; urgency=medium
2232
3233 [ Albert Astals Cid ]
debian/control+12−8
@@ -30,9 +30,13 @@ Build-Depends: cmake,
3030 libqt5xmlpatterns5-dev,
3131 libsystemsettings-dev,
3232 libudev-dev,
33− libunity-api-dev (>= 7.104),
33+ libunity-api-dev (>= 7.106),
3434 libusermetricsoutput1-dev,
35− libxcb1-dev,
35+# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
36+ libx11-dev[!armhf],
37+ libxcb1-dev[!armhf],
38+ libxi-dev[!armhf],
39+# End of X11 libs
3640 pkg-config,
3741 python3-all:any,
3842 python3-setuptools,
@@ -49,7 +53,7 @@ Build-Depends: cmake,
4953 qtdeclarative5-dev (>= 5.4),
5054 qtdeclarative5-dev-tools,
5155 qtdeclarative5-private-dev (>= 5.4),
52− qtdeclarative5-qtmultimedia-plugin,
56+ qtdeclarative5-qtmultimedia-plugin (>= 5.4.1-1ubuntu19~overlay2),
5357 qtdeclarative5-ubuntu-content1,
5458 qtdeclarative5-ubuntu-settings-components (>= 0.6),
5559 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1676) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1676),
@@ -77,6 +81,7 @@ Description: Indicators client test application
7781Package: unity8-greeter
7882Architecture: any
7983Depends: unity8 (= ${binary:Version}),
84+ unity-system-compositor,
8085 ${misc:Depends},
8186 ${shlibs:Depends}
8287Recommends: lightdm
@@ -121,7 +126,6 @@ Depends: dmz-cursor-theme,
121126 ${shlibs:Depends},
122127Recommends: unity-scope-click,
123128 unity-scope-mediascanner2,
124− unity-scope-scopes,
125129Breaks: indicator-network (<< 0.5.1+14.10.20141014),
126130 ubuntu-touch-session (<< 0.107),
127131 unity8-greeter (<< 7.89),
@@ -139,10 +143,10 @@ Depends: qml-module-qtquick-layouts,
139143 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
140144 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
141145 ubuntu-thumbnailer-impl-0,
142− unity-application-impl-12,
146+ unity-application-impl-13,
143147 unity-notifications-impl-3,
144148 unity-plugin-scopes | unity-scopes-impl,
145− unity-scopes-impl-7,
149+ unity-scopes-impl-9,
146150 unity8-fake-env | unity-application-impl,
147151 ${misc:Depends},
148152Breaks: unity8 (<< 7.86),
@@ -185,7 +189,7 @@ Pre-Depends: ${misc:Pre-Depends},
185189Depends: ${misc:Depends},
186190 ${shlibs:Depends},
187191Provides: unity-application-impl,
188− unity-application-impl-12,
192+ unity-application-impl-13,
189193Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
190194Description: Fake environment for running Unity 8 shell
191195 Provides fake implementations of some QML modules used by Unity 8 shell
@@ -195,7 +199,7 @@ Package: unity8-private
195199Architecture: any
196200Multi-Arch: same
197201Pre-Depends: ${misc:Pre-Depends},
198−Depends: accountsservice-ubuntu-schemas (>= 0.0.3),
202+Depends: accountsservice-ubuntu-schemas (>= 0.0.5),
199203 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
200204 libhardware2,
201205 pay-service,
debian/rules−4
@@ -11,10 +11,6 @@ export NO_PNG_PKG_MANGLE=1
1111%:
1212 dh $@ --parallel --fail-missing --with python3
1313
14−override_dh_auto_clean:
15− dh_auto_clean
16− rm -rf builddir
17−
1814override_dh_auto_configure:
1915 # Debian defines CMAKE_INSTALL_LOCALSTATEDIR as /usr/var, which is wrong.
2016 # So until Debian bug 719148 is fixed, do it ourselves.
debian/tests/autopilot.shnew file+13
@@ -0,0 +1,13 @@
1+#!/bin/sh
2+
3+# log all commands and abort on error
4+set -xe
5+
6+if [ ! -f /system/build.prop ]; then
7+ echo "WARNING: Skipping autopilot test, will only run on devices at the moment."
8+ exit 0
9+fi
10+
11+initctl --session stop unity8
12+autopilot3 run --verbose --format xml --output "${ADT_ARTIFACTS}/unity8.xml" unity8
13+initctl --session start unity8
debian/tests/control+5
@@ -3,3 +3,8 @@ Restrictions: allow-stderr
33Depends: @,
44 @builddeps@,
55 xvfb,
6+
7+Tests: autopilot.sh
8+Restrictions: allow-stderr,
9+ isolation-machine,
10+Depends: unity8-autopilot,
debian/tests/qmluitests.sh+4−2
@@ -1,5 +1,8 @@
11#!/bin/sh
22
3+# log all commands and abort on error
4+set -xe
5+
36SHELL_QML_PATH=$(pkg-config --variable=plugindir unity-shell-api)
47UNITY_SOURCE_DIR=$(readlink -f $(dirname $(readlink -f $0))/../..)
58
@@ -15,5 +18,4 @@ dh_auto_build --parallel -- -C tests/utils
1518
1619export UNITY_SOURCE_DIR
1720
18−# FIXME: --parallel here causes some failures
19−dh_auto_build -- -k xvfballtests
21+dh_auto_build --parallel -- -k xvfballtests
debian/unity8-greeter.install+2
@@ -1,2 +1,4 @@
1+data/unity8-greeter-wrapper usr/bin/
2+data/unity8-greeter-init.conf usr/share/upstart/sessions/
13usr/share/lightdm/greeters/unity8-greeter.desktop
24usr/share/lightdm/lightdm.conf.d/51-unity8-greeter.conf
debian/unity8-private.install+1
@@ -12,6 +12,7 @@ usr/lib/*/unity8/qml/ScreenGrabber
1212usr/lib/*/unity8/qml/SessionBroadcast
1313usr/lib/*/unity8/qml/Ubuntu
1414usr/lib/*/unity8/qml/Unity
15+usr/lib/*/unity8/qml/UInput
1516usr/lib/*/unity8/qml/Utils
1617usr/lib/*/unity8/qml/Wizard
1718usr/share/accountsservice/interfaces
plugins/AccountsService/AccountsService.cpp+61
@@ -19,6 +19,7 @@
1919#include "AccountsService.h"
2020#include "AccountsServiceDBusAdaptor.h"
2121
22+#include <QDBusInterface>
2223#include <QFile>
2324#include <QStringList>
2425#include <QDebug>
@@ -35,6 +36,11 @@ AccountsService::AccountsService(QObject* parent, const QString &user)
3536 m_hereEnabled(false),
3637 m_hereLicensePath() // null means not set yet
3738{
39+ m_unityInput = new QDBusInterface(QStringLiteral("com.canonical.Unity.Input"),
40+ QStringLiteral("/com/canonical/Unity/Input"),
41+ QStringLiteral("com.canonical.Unity.Input"),
42+ QDBusConnection::SM_BUSNAME(), this);
43+
3844 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
3945 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
4046
@@ -58,6 +64,8 @@ void AccountsService::setUser(const QString &user)
5864 updateEnableLauncherWhileLocked(false);
5965 updateEnableIndicatorsWhileLocked(false);
6066 updateBackgroundFile(false);
67+ updateMouseCursorSpeed();
68+ updateTouchpadCursorSpeed();
6169 updateStatsWelcomeScreen(false);
6270 updatePasswordDisplayHint(false);
6371 updateFailedLogins(false);
@@ -246,6 +254,52 @@ void AccountsService::updateBackgroundFile(bool async)
246254 }
247255}
248256
257+void AccountsService::updateMouseCursorSpeed()
258+{
259+ QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
260+ QStringLiteral("com.ubuntu.AccountsService.Input"),
261+ QStringLiteral("MouseCursorSpeed"));
262+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
263+
264+ connect(watcher, &QDBusPendingCallWatcher::finished,
265+ this, [this](QDBusPendingCallWatcher* watcher) {
266+
267+ QDBusPendingReply<QVariant> reply = *watcher;
268+ watcher->deleteLater();
269+ if (reply.isError()) {
270+ qWarning() << "Failed to get 'MouseCursorSpeed' property - " << reply.error().message();
271+ return;
272+ }
273+
274+ // Merely proxy this along to USC. We don't care about keeping a copy
275+ // or exporting it internally.
276+ m_unityInput->asyncCall(QStringLiteral("setMouseCursorSpeed"), reply.value());
277+ });
278+}
279+
280+void AccountsService::updateTouchpadCursorSpeed()
281+{
282+ QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
283+ QStringLiteral("com.ubuntu.AccountsService.Input"),
284+ QStringLiteral("TouchpadCursorSpeed"));
285+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
286+
287+ connect(watcher, &QDBusPendingCallWatcher::finished,
288+ this, [this](QDBusPendingCallWatcher* watcher) {
289+
290+ QDBusPendingReply<QVariant> reply = *watcher;
291+ watcher->deleteLater();
292+ if (reply.isError()) {
293+ qWarning() << "Failed to get 'TouchpadCursorSpeed' property - " << reply.error().message();
294+ return;
295+ }
296+
297+ // Merely proxy this along to USC. We don't care about keeping a copy
298+ // or exporting it internally.
299+ m_unityInput->asyncCall(QStringLiteral("setTouchpadCursorSpeed"), reply.value());
300+ });
301+}
302+
249303void AccountsService::updateStatsWelcomeScreen(bool async)
250304{
251305 QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
@@ -423,6 +477,13 @@ void AccountsService::onPropertiesChanged(const QString &user, const QString &in
423477 if (changed.contains(QStringLiteral("FailedLogins"))) {
424478 updateFailedLogins();
425479 }
480+ } else if (interface == QLatin1String("com.ubuntu.AccountsService.Input")) {
481+ if (changed.contains(QStringLiteral("MouseCursorSpeed"))) {
482+ updateMouseCursorSpeed();
483+ }
484+ if (changed.contains(QStringLiteral("TouchpadCursorSpeed"))) {
485+ updateTouchpadCursorSpeed();
486+ }
426487 } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) {
427488 if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) {
428489 updateStatsWelcomeScreen();
plugins/AccountsService/AccountsService.h+4
@@ -23,6 +23,7 @@
2323#include <QString>
2424
2525class AccountsServiceDBusAdaptor;
26+class QDBusInterface;
2627
2728class AccountsService: public QObject
2829{
@@ -112,6 +113,8 @@ private:
112113 void updateEnableLauncherWhileLocked(bool async = true);
113114 void updateEnableIndicatorsWhileLocked(bool async = true);
114115 void updateBackgroundFile(bool async = true);
116+ void updateMouseCursorSpeed();
117+ void updateTouchpadCursorSpeed();
115118 void updateStatsWelcomeScreen(bool async = true);
116119 void updatePasswordDisplayHint(bool async = true);
117120 void updateFailedLogins(bool async = true);
@@ -119,6 +122,7 @@ private:
119122 void updateHereLicensePath(bool async = true);
120123
121124 AccountsServiceDBusAdaptor *m_service;
125+ QDBusInterface *m_unityInput;
122126 QString m_user;
123127 bool m_demoEdges;
124128 bool m_enableLauncherWhileLocked;
plugins/CMakeLists.txt+1
@@ -22,6 +22,7 @@ add_subdirectory(Powerd)
2222add_subdirectory(SessionBroadcast)
2323add_subdirectory(ScreenGrabber)
2424add_subdirectory(Ubuntu)
25+add_subdirectory(UInput)
2526add_subdirectory(Unity)
2627add_subdirectory(Utils)
2728add_subdirectory(Wizard)
plugins/Cursor/MousePointer.cpp+4
@@ -42,6 +42,10 @@ void MousePointer::handleMouseEvent(ulong timestamp, QPointF movement, Qt::Mouse
4242 return;
4343 }
4444
45+ if (!movement.isNull()) {
46+ Q_EMIT mouseMoved();
47+ }
48+
4549 qreal newX = x() + movement.x();
4650 if (newX < 0) {
4751 Q_EMIT pushedLeftBoundary(qAbs(newX), buttons);
plugins/Cursor/MousePointer.h+1
@@ -48,6 +48,7 @@ public Q_SLOTS:
4848Q_SIGNALS:
4949 void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons);
5050 void pushedRightBoundary(qreal amount, Qt::MouseButtons buttons);
51+ void mouseMoved();
5152
5253protected:
5354 void itemChange(ItemChange change, const ItemChangeData &value) override;
plugins/Dash/AudioProgressBar.qmlnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Dash 0.1
20+
21+Item {
22+ id: root
23+
24+ implicitHeight: progressBarImage.height
25+
26+ property url source
27+ readonly property double progress: AudioUrlComparer.compare(source, DashAudioPlayer.currentSource) ? DashAudioPlayer.progress : 0
28+
29+ Image {
30+ id: progressBarImage
31+ anchors { left: parent.left; right: parent.right }
32+ height: units.dp(6)
33+ source: "graphics/music_progress_bg.png"
34+ sourceSize.width: width
35+ sourceSize.height: height
36+ }
37+
38+ UbuntuShape {
39+ id: progressBarFill
40+ objectName: "progressBarFill"
41+
42+ readonly property int maxWidth: progressBarImage.width
43+
44+ anchors {
45+ left: progressBarImage.left
46+ right: progressBarImage.right
47+ verticalCenter: progressBarImage.verticalCenter
48+ rightMargin: maxWidth - (maxWidth * root.progress)
49+ }
50+ height: units.dp(2)
51+ backgroundColor: UbuntuColors.orange
52+ }
53+}
plugins/Dash/CMakeLists.txt+3
@@ -38,3 +38,6 @@ target_link_libraries(Dash-qml
3838qt5_use_modules(Dash-qml Qml Quick Concurrent)
3939
4040add_unity8_plugin(Dash 0.1 Dash TARGETS Dash-qml)
41+
42+install(FILES graphics/music_progress_bg.png DESTINATION ${SHELL_INSTALL_QML}/Dash/graphics/)
43+file(COPY graphics/music_progress_bg.png DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/graphics/)
plugins/Dash/CardAudioProgress.qmlnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Dash 0.1
20+
21+Item {
22+ id: root
23+
24+ implicitHeight: positionLabel.y + positionLabel.height
25+ visible: AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)
26+
27+ property int duration: 0
28+ property alias source: progress.source
29+ property color color: theme.palette.normal.baseText
30+ readonly property int position: root.visible ? DashAudioPlayer.position / 1000 : 0
31+
32+ AudioProgressBar {
33+ id: progress
34+ anchors { left: parent.left; right: parent.right }
35+ }
36+
37+ Label {
38+ id: positionLabel
39+ anchors {
40+ left: parent.left
41+ top: progress.bottom
42+ }
43+ verticalAlignment: Text.AlignBottom
44+ fontSize: "x-small"
45+ text: DashAudioPlayer.lengthToString(root.position)
46+ color: root.color
47+ }
48+
49+ Label {
50+ anchors {
51+ right: parent.right
52+ top: progress.bottom
53+ }
54+ verticalAlignment: Text.AlignBottom
55+ fontSize: "x-small"
56+ text: DashAudioPlayer.lengthToString(duration)
57+ color: root.color
58+ }
59+}
plugins/Dash/CardCreator.js+186−28
@@ -16,9 +16,9 @@
1616
1717.pragma library
1818
19−// %1 is the template["card-background"] string
20−// %2 is the template["card-background"]["elements"][0]
21−// %3 is the template["card-background"]["elements"][1]
19+// %1 is the template["card-background"]["elements"][0]
20+// %2 is the template["card-background"]["elements"][1]
21+// %3 is the template["card-background"] string
2222var kBackgroundLoaderCode = 'Loader {\n\
2323 id: backgroundLoader; \n\
2424 objectName: "backgroundLoader"; \n\
@@ -46,14 +46,14 @@ var kBackgroundLoaderCode = 'Loader {\n\
4646 objectName: "backgroundImage"; \n\
4747 source: { \n\
4848 if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
49− else return "%1"; \n\
49+ else return %3; \n\
5050 } \n\
5151 } \n\
5252 function getColor(index) { \n\
5353 if (cardData && typeof cardData["background"] === "object" \n\
5454 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
5555 return cardData["background"]["elements"][index]; \n\
56− } else return index === 0 ? %2 : %3; \n\
56+ } else return index === 0 ? %1 : %2; \n\
5757 } \n\
5858 } \n\
5959 }\n';
@@ -61,6 +61,10 @@ var kBackgroundLoaderCode = 'Loader {\n\
6161// %1 is used as anchors of artShapeHolder
6262// %2 is used as image width
6363// %3 is used as image height
64+// %4 is used for artShapeSource.hideSource and inner Loader visible
65+// %5 is used as aspect ratio fallback
66+// %6 is injected as code to artImage
67+// %7 is used as image fallback
6468var kArtShapeHolderCode = 'Item { \n\
6569 id: artShapeHolder; \n\
6670 height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
@@ -69,13 +73,13 @@ var kArtShapeHolderCode = 'Item { \n\
6973 Loader { \n\
7074 id: artShapeLoader; \n\
7175 objectName: "artShapeLoader"; \n\
72− active: cardData && cardData["art"] || false; \n\
76+ readonly property string cardArt: cardData && cardData["art"] || %7; \n\
77+ active: cardArt != ""; \n\
7378 asynchronous: root.asynchronous; \n\
7479 visible: status == Loader.Ready; \n\
7580 sourceComponent: Item { \n\
7681 id: artShape; \n\
7782 objectName: "artShape"; \n\
78− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true; \n\
7983 visible: image.status == Image.Ready; \n\
8084 readonly property alias image: artImage; \n\
8185 ShaderEffectSource { \n\
@@ -84,11 +88,11 @@ var kArtShapeHolderCode = 'Item { \n\
8488 anchors.centerIn: parent; \n\
8589 width: 1; \n\
8690 height: 1; \n\
87− hideSource: doShapeItem; \n\
91+ hideSource: %4; \n\
8892 } \n\
8993 Loader { \n\
9094 anchors.fill: parent; \n\
91− visible: artShape.doShapeItem; \n\
95+ visible: %4; \n\
9296 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent; \n\
9397 Component { \n\
9498 id: artShapeShapeComponent; \n\
@@ -112,7 +116,7 @@ var kArtShapeHolderCode = 'Item { \n\
112116 } \n\
113117 } \n\
114118 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
115− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
119+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : %5; \n\
116120 Component.onCompleted: { updateWidthHeightBindings(); } \n\
117121 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
118122 function updateWidthHeightBindings() { \n\
@@ -127,15 +131,62 @@ var kArtShapeHolderCode = 'Item { \n\
127131 CroppedImageMinimumSourceSize { \n\
128132 id: artImage; \n\
129133 objectName: "artImage"; \n\
130− source: cardData && cardData["art"] || ""; \n\
134+ source: artShapeLoader.cardArt; \n\
131135 asynchronous: root.asynchronous; \n\
132136 width: %2; \n\
133137 height: %3; \n\
138+ %6 \n\
134139 } \n\
135140 } \n\
136141 } \n\
137142 }\n';
138143
144+// %1 is anchors.fill
145+// %2 is width
146+// %3 is height
147+var kAudioButtonCode = 'AbstractButton { \n\
148+ id: audioButton; \n\
149+ anchors.fill: %1; \n\
150+ width: %2; \n\
151+ height: %3; \n\
152+ readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
153+ UbuntuShape { \n\
154+ anchors.fill: parent; \n\
155+ visible: parent.pressed; \n\
156+ radius: "medium"; \n\
157+ } \n\
158+ Rectangle { \n\
159+ color: Qt.rgba(0, 0, 0, 0.5); \n\
160+ anchors.centerIn: parent; \n\
161+ width: parent.width * 0.5; \n\
162+ height: width; \n\
163+ radius: width / 2; \n\
164+ } \n\
165+ Icon { \n\
166+ anchors.centerIn: parent; \n\
167+ width: parent.width * 0.3; \n\
168+ height: width; \n\
169+ opacity: 0.9; \n\
170+ name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start"; \n\
171+ color: "white"; \n\
172+ } \n\
173+ onClicked: { \n\
174+ if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) { \n\
175+ if (DashAudioPlayer.playing) { \n\
176+ DashAudioPlayer.pause(); \n\
177+ } else { \n\
178+ DashAudioPlayer.play(); \n\
179+ } \n\
180+ } else { \n\
181+ var playlist = (cardData["quickPreviewData"] && cardData["quickPreviewData"]["playlist"]) || null; \n\
182+ DashAudioPlayer.playSource(source, playlist); \n\
183+ } \n\
184+ } \n\
185+ onPressAndHold: { \n\
186+ root.pressAndHold(); \n\
187+ } \n\
188+ }';
189+
139190var kOverlayLoaderCode = 'Loader { \n\
140191 id: overlayLoader; \n\
141192 readonly property real overlayHeight: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
@@ -205,16 +256,19 @@ var kMascotShapeLoaderCode = 'Loader { \n\
205256
206257// %1 is used as anchors of mascotImage
207258// %2 is used as visible of mascotImage
259+// %3 is injected as code to mascotImage
260+// %4 is used as fallback image
208261var kMascotImageCode = 'CroppedImageMinimumSourceSize { \n\
209262 id: mascotImage; \n\
210263 objectName: "mascotImage"; \n\
211264 anchors { %1 } \n\
212− source: cardData && cardData["mascot"] || ""; \n\
265+ source: cardData && cardData["mascot"] || %4; \n\
213266 width: units.gu(6); \n\
214267 height: units.gu(5.625); \n\
215268 horizontalAlignment: Image.AlignHCenter; \n\
216269 verticalAlignment: Image.AlignVCenter; \n\
217270 visible: %2; \n\
271+ %3 \n\
218272 }\n';
219273
220274// %1 is used as anchors of titleLabel
@@ -316,6 +370,34 @@ var kSummaryLabelCode = 'Label { \n\
316370 color: %3; \n\
317371 }\n';
318372
373+// %1 is used as bottom anchor of audio progress bar
374+// %2 is used as left anchor of audio progress bar
375+// %3 is used as text color
376+var kAudioProgressBarCode = 'CardAudioProgress { \n\
377+ id: audioProgressBar; \n\
378+ duration: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["duration"]) || 0; \n\
379+ source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
380+ anchors { \n\
381+ bottom: %1; \n\
382+ left: %2; \n\
383+ right: parent.right; \n\
384+ margins: units.gu(1); \n\
385+ } \n\
386+ color: %3; \n\
387+ }';
388+
389+function sanitizeColor(colorString) {
390+ if (colorString !== undefined) {
391+ if (colorString.match(/^[#a-z0-9]*$/i) === null) {
392+ // This is not the perfect regexp for color
393+ // but what we're trying to do here is just protect
394+ // against injection so it's ok
395+ return "";
396+ }
397+ }
398+ return colorString;
399+}
400+
319401function cardString(template, components) {
320402 var code;
321403
@@ -323,7 +405,6 @@ function cardString(template, components) {
323405
324406 code = 'AbstractButton { \n\
325407 id: root; \n\
326− property var components; \n\
327408 property var cardData; \n\
328409 property string artShapeStyle: "inset"; \n\
329410 property string backgroundShapeStyle: "inset"; \n\
@@ -341,7 +422,8 @@ function cardString(template, components) {
341422
342423 var hasArt = components["art"] && components["art"]["field"] || false;
343424 var hasSummary = components["summary"] || false;
344− var artAndSummary = hasArt && hasSummary && components["art"]["conciergeMode"] !== true;
425+ var isConciergeMode = components["art"] && components["art"]["conciergeMode"] || false;
426+ var artAndSummary = hasArt && hasSummary && !isConciergeMode;
345427 var isHorizontal = template["card-layout"] === "horizontal";
346428 var hasBackground = (!isHorizontal && (template["card-background"] || components["background"] || artAndSummary)) ||
347429 (hasSummary && (template["card-background"] || components["background"]));
@@ -351,21 +433,42 @@ function cardString(template, components) {
351433 var headerAsOverlay = hasArt && template && template["overlay"] === true && (hasTitle || hasMascot);
352434 var hasSubtitle = hasTitle && components["subtitle"] || false;
353435 var hasHeaderRow = hasMascot && hasTitle;
354− var hasAttributes = hasTitle && components["attributes"]["field"] || false;
436+ var hasAttributes = hasTitle && components["attributes"] && components["attributes"]["field"] || false;
437+ var isAudio = template["quick-preview-type"] === "audio";
438+
439+ if (isAudio) {
440+ // For now we only support audio cards with [optional] art, title, subtitle
441+ // in horizontal mode
442+ // Anything else makes it behave not like an audio card
443+ if (hasSummary) isAudio = false;
444+ if (!isHorizontal) isAudio = false;
445+ if (hasMascot) isAudio = false;
446+ if (hasEmblem) isAudio = false;
447+ if (headerAsOverlay) isAudio = false;
448+ if (hasAttributes) isAudio = false;
449+ }
355450
356451 if (hasBackground) {
357− var templateCardBackground = (template && typeof template["card-background"] === "string") ? template["card-background"] : "";
452+ var templateCardBackground;
453+ if (template && typeof template["card-background"] === "string") {
454+ templateCardBackground = 'decodeURI("' + encodeURI(template["card-background"]) + '")';
455+ } else {
456+ templateCardBackground = '""';
457+ }
458+
358459 var backgroundElements0;
359460 var backgroundElements1;
360461 if (template && typeof template["card-background"] === "object" && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
361− if (template["card-background"]["elements"][0] !== undefined) {
362− backgroundElements0 = '"%1"'.arg(template["card-background"]["elements"][0]);
462+ var element0 = sanitizeColor(template["card-background"]["elements"][0]);
463+ var element1 = sanitizeColor(template["card-background"]["elements"][1]);
464+ if (element0 !== undefined) {
465+ backgroundElements0 = '"%1"'.arg(element0);
363466 }
364− if (template["card-background"]["elements"][1] !== undefined) {
365− backgroundElements1 = '"%1"'.arg(template["card-background"]["elements"][1]);
467+ if (element1 !== undefined) {
468+ backgroundElements1 = '"%1"'.arg(element1);
366469 }
367470 }
368− code += kBackgroundLoaderCode.arg(templateCardBackground).arg(backgroundElements0).arg(backgroundElements1);
471+ code += kBackgroundLoaderCode.arg(backgroundElements0).arg(backgroundElements1).arg(templateCardBackground);
369472 }
370473
371474 if (hasArt) {
@@ -390,11 +493,21 @@ function cardString(template, components) {
390493 heightCode = 'width / artShape.aspect';
391494 }
392495
393− code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode);
496+ var aspectRatio = components["art"] && components["art"]["aspect-ratio"] || 1;
497+ if (isNaN(aspectRatio)) {
498+ aspectRatio = 1;
499+ }
394500 var fallback = components["art"] && components["art"]["fallback"] || "";
501+ fallback = encodeURI(fallback);
502+ var fallbackStatusCode = "";
503+ var fallbackURICode = '""';
395504 if (fallback !== "") {
396− code += 'Connections { target: artShapeLoader.item ? artShapeLoader.item.image : null; onStatusChanged: if (artShapeLoader.item.image.status === Image.Error) artShapeLoader.item.image.source = "%1"; } \n'.arg(fallback);
505+ // fallbackStatusCode has %6 in it because we want to substitute it for fallbackURICode
506+ // which in kArtShapeHolderCode is %7
507+ fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %7;';
508+ fallbackURICode = 'decodeURI("%1")'.arg(fallback);
397509 }
510+ code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode).arg(isConciergeMode ? "false" : "true").arg(aspectRatio).arg(fallbackStatusCode).arg(fallbackURICode);
398511 } else {
399512 code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
400513 }
@@ -421,17 +534,22 @@ function cardString(template, components) {
421534 topMargin: units.gu(1);\n';
422535 }
423536 }
537+
424538 var headerLeftAnchor;
425539 var headerLeftAnchorHasMargin = false;
426540 if (isHorizontal && hasArt) {
427541 headerLeftAnchor = 'left: artShapeHolder.right; \n\
428542 leftMargin: units.gu(1);\n';
429543 headerLeftAnchorHasMargin = true;
544+ } else if (isHorizontal && isAudio) {
545+ headerLeftAnchor = 'left: audioButton.right; \n\
546+ leftMargin: units.gu(1);\n';
547+ headerLeftAnchorHasMargin = true;
430548 } else {
431549 headerLeftAnchor = 'left: parent.left;\n';
432550 }
433551
434− var touchdownOnArtShape = !hasBackground && hasArt && !hasMascot && !hasSummary;
552+ var touchdownOnArtShape = !hasBackground && hasArt && !hasMascot && !hasSummary && !isAudio;
435553
436554 if (hasHeaderRow) {
437555 code += 'readonly property int headerHeight: row.height;\n'
@@ -445,6 +563,14 @@ function cardString(template, components) {
445563 } else {
446564 code += 'readonly property int headerHeight: attributesRow.height;\n'
447565 }
566+ } else if (isAudio) {
567+ if (hasSubtitle) {
568+ code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + audioProgressBar.height + audioProgressBar.anchors.topMargin;\n'
569+ } else if (hasTitle) {
570+ code += 'readonly property int headerHeight: titleLabel.height + audioProgressBar.height + audioProgressBar.anchors.topMargin;\n'
571+ } else {
572+ code += 'readonly property int headerHeight: audioProgressBar.height;\n'
573+ }
448574 } else if (hasSubtitle) {
449575 code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
450576 } else if (hasTitle) {
@@ -473,11 +599,17 @@ function cardString(template, components) {
473599 }
474600
475601 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
476− mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
477602 var fallback = components["mascot"] && components["mascot"]["fallback"] || "";
603+ fallback = encodeURI(fallback);
604+ var fallbackStatusCode = "";
605+ var fallbackURICode = '""';
478606 if (fallback !== "") {
479− code += 'Connections { target: mascotImage; onStatusChanged: if (mascotImage.status === Image.Error) mascotImage.source = "%1"; } \n'.arg(fallback);
607+ // fallbackStatusCode has %4 in it because we want to substitute it for fallbackURICode
608+ // which in kMascotImageCode is %4
609+ fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %4;';
610+ fallbackURICode = 'decodeURI("%1")'.arg(fallback);
480611 }
612+ mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible).arg(fallbackStatusCode).arg(fallbackURICode);
481613 }
482614
483615 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white")';
@@ -632,6 +764,30 @@ function cardString(template, components) {
632764 code += mascotShapeCode + mascotCode + titleSubtitleCode;
633765 }
634766
767+ if (isAudio) {
768+ var audioProgressBarLeftAnchor = 'audioButton.right';
769+ var audioProgressBarBottomAnchor = 'audioButton.bottom';
770+ var audioProgressBarTextColor = 'root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText';
771+
772+ code += kAudioProgressBarCode.arg(audioProgressBarBottomAnchor)
773+ .arg(audioProgressBarLeftAnchor)
774+ .arg(audioProgressBarTextColor);
775+
776+ var audioButtonAnchorsFill;
777+ var audioButtonWidth;
778+ var audioButtonHeight;
779+ if (hasArt) {
780+ audioButtonAnchorsFill = 'artShapeHolder';
781+ audioButtonWidth = 'undefined';
782+ audioButtonHeight = 'undefined';
783+ } else {
784+ audioButtonAnchorsFill = 'undefined';
785+ audioButtonWidth = 'height';
786+ audioButtonHeight = '(root.fixedHeaderHeight > 0 ? root.fixedHeaderHeight : headerHeight) + 2 * units.gu(1)';
787+ }
788+ code += kAudioButtonCode.arg(audioButtonAnchorsFill).arg(audioButtonWidth).arg(audioButtonHeight);
789+ }
790+
635791 if (hasSummary) {
636792 var summaryTopAnchor;
637793 if (isHorizontal && hasArt) summaryTopAnchor = 'artShapeHolder.bottom';
@@ -670,6 +826,8 @@ function cardString(template, components) {
670826 var implicitHeight = 'implicitHeight: ';
671827 if (hasSummary) {
672828 implicitHeight += 'summary.y + summary.height + units.gu(1);\n';
829+ } else if (isAudio) {
830+ implicitHeight += 'audioButton.height;\n';
673831 } else if (headerAsOverlay) {
674832 implicitHeight += 'artShapeHolder.height;\n';
675833 } else if (hasHeaderRow) {
@@ -696,7 +854,7 @@ function cardString(template, components) {
696854 return code;
697855}
698856
699−function createCardComponent(parent, template, components) {
857+function createCardComponent(parent, template, components, identifier) {
700858 var imports = 'import QtQuick 2.4; \n\
701859 import Ubuntu.Components 1.3; \n\
702860 import Ubuntu.Settings.Components 0.1; \n\
@@ -706,7 +864,7 @@ function createCardComponent(parent, template, components) {
706864 var code = imports + 'Component {\n' + card + '}\n';
707865
708866 try {
709− return Qt.createQmlObject(code, parent, "createCardComponent");
867+ return Qt.createQmlObject(code, parent, identifier);
710868 } catch (e) {
711869 console.error("ERROR: Invalid component created.");
712870 console.error("Template:");
plugins/Dash/CardCreatorCache.qml+1−1
@@ -32,7 +32,7 @@ QtObject {
3232 var allString = tString + cString;
3333 var component = cache[allString];
3434 if (component === undefined) {
35− component = CardCreator.createCardComponent(root, template, components);
35+ component = CardCreator.createCardComponent(root, template, components, allString);
3636 cache[allString] = component;
3737 }
3838 return component;
plugins/Dash/DashAudioPlayer.qmlnew file+96
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+pragma Singleton
18+import QtQuick 2.4
19+import QtMultimedia 5.6
20+import Dash 0.1
21+
22+QtObject {
23+ readonly property real progress: audio.position / audio.duration
24+ readonly property bool playing: audio.playbackState === Audio.PlayingState
25+ readonly property bool paused: audio.playbackState === Audio.PausedState
26+ readonly property bool stopped: audio.playbackState === Audio.StoppedState
27+ readonly property alias position: audio.position
28+ readonly property url currentSource: audio.playlist.currentItemSource
29+
30+ function playSource(newSource, newPlaylist) {
31+ stop();
32+ audio.playlist.clear();
33+ if (newPlaylist) {
34+ // Look for newSource in newPlaylist
35+ var sourceIndex = -1;
36+ for (var i in newPlaylist) {
37+ if (AudioUrlComparer.compare(newSource, newPlaylist[i])) {
38+ sourceIndex = i;
39+ break;
40+ }
41+ }
42+ var urls = [];
43+ if (sourceIndex === -1 && newSource != "") {
44+ // If the playing song is not in the playlist, add it
45+ urls.push(newSource);
46+ sourceIndex = 0;
47+ }
48+ for (var i in newPlaylist) {
49+ urls.push(newPlaylist[i]);
50+ }
51+ audio.playlist.addItems(urls);
52+ audio.playlist.currentIndex = sourceIndex;
53+ } else {
54+ audio.playlist.addItem(newSource);
55+ audio.playlist.currentIndex = 0;
56+ }
57+ play();
58+ }
59+
60+ function stop() {
61+ audio.stop();
62+ }
63+
64+ function play() {
65+ audio.play();
66+ }
67+
68+ function pause() {
69+ audio.pause();
70+ }
71+
72+ property QtObject audio: Audio {
73+ id: audio
74+ objectName: "audio"
75+ playlist: Playlist {
76+ objectName: "playlist"
77+ }
78+
79+ onErrorStringChanged: console.warn("Dash Audio player error:", errorString)
80+ }
81+
82+ function lengthToString(s) {
83+ if (typeof(s) !== "number" || s < 0) return "";
84+
85+ var sec = "" + s % 60;
86+ if (sec.length == 1) sec = "0" + sec;
87+ var hour = Math.floor(s / 3600);
88+ if (hour < 1) {
89+ return Math.floor(s / 60) + ":" + sec;
90+ } else {
91+ var min = "" + Math.floor(s / 60) % 60;
92+ if (min.length == 1) min = "0" + min;
93+ return hour + ":" + min + ":" + sec;
94+ }
95+ }
96+}
plugins/Dash/graphics/music_progress_bg.pngnew file

Binary file not shown.

plugins/Dash/listviewwithpageheader.cpp+23−10
@@ -219,13 +219,7 @@ void ListViewWithPageHeader::setDelegate(QQmlComponent *delegate)
219219 Q_FOREACH(ListItem *item, m_visibleItems)
220220 releaseItem(item);
221221 m_visibleItems.clear();
222− m_firstVisibleIndex = -1;
223− adjustMinYExtent();
224− setContentY(0);
225− m_clipItem->setY(0);
226− if (m_topSectionItem) {
227− QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
228− }
222+ initializeValuesForEmptyList();
229223
230224 m_delegateModel->setDelegate(delegate);
231225
@@ -236,6 +230,17 @@ void ListViewWithPageHeader::setDelegate(QQmlComponent *delegate)
236230 }
237231}
238232
233+void ListViewWithPageHeader::initializeValuesForEmptyList()
234+{
235+ m_firstVisibleIndex = -1;
236+ adjustMinYExtent();
237+ setContentY(0);
238+ m_clipItem->setY(0);
239+ if (m_topSectionItem) {
240+ QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
241+ }
242+}
243+
239244QQuickItem *ListViewWithPageHeader::header() const
240245{
241246 return m_headerItem;
@@ -835,7 +840,7 @@ bool ListViewWithPageHeader::removeNonVisibleItems(qreal bufferFrom, qreal buffe
835840 }
836841 }
837842 if (!foundVisible) {
838− m_firstVisibleIndex = -1;
843+ initializeValuesForEmptyList();
839844 }
840845 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
841846 adjustMinYExtent();
@@ -1092,7 +1097,11 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
10921097 }
10931098
10941099 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
1095− adjustMinYExtent();
1100+ if (m_visibleItems.isEmpty()) {
1101+ initializeValuesForEmptyList();
1102+ } else {
1103+ adjustMinYExtent();
1104+ }
10961105 }
10971106
10981107 for (int i = 0; i < m_visibleItems.count(); ++i) {
@@ -1177,7 +1186,7 @@ void ListViewWithPageHeader::headerHeightChanged(qreal newHeaderHeight, qreal ol
11771186
11781187void ListViewWithPageHeader::adjustMinYExtent()
11791188{
1180− if (m_visibleItems.isEmpty()) {
1189+ if (m_visibleItems.isEmpty() || contentHeight() < height()) {
11811190 m_minYExtent = 0;
11821191 } else {
11831192 qreal nonCreatedHeight = 0;
@@ -1359,6 +1368,10 @@ void ListViewWithPageHeader::updatePolish()
13591368
13601369 m_contentHeightDirty = false;
13611370 adjustMinYExtent();
1371+ if (contentHeight < height()) {
1372+ // need this since in the previous call to adjustMinYExtent contentHeight is not set yet
1373+ m_minYExtent = 0;
1374+ }
13621375 m_inContentHeightKeepHeaderShown = m_headerItem && m_headerItem->y() == contentY();
13631376 setContentHeight(contentHeight);
13641377 m_inContentHeightKeepHeaderShown = false;
plugins/Dash/listviewwithpageheader.h+1
@@ -168,6 +168,7 @@ private:
168168 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
169169 QQuickItem *getSectionItem(const QString &sectionText);
170170 void updateSectionItem(int modelIndex);
171+ void initializeValuesForEmptyList();
171172
172173 QQmlDelegateModel *m_delegateModel;
173174
plugins/Dash/plugin.cpp+35
@@ -23,6 +23,38 @@
2323#include "verticaljournal.h"
2424
2525#include <QAbstractItemModel>
26+#include <QUrlQuery>
27+
28+static QUrl oauthCleanedUrl(QUrl u)
29+{
30+ QUrlQuery q(u);
31+ q.removeQueryItem("oauth_nonce");
32+ q.removeQueryItem("oauth_timestamp");
33+ q.removeQueryItem("oauth_consumer_key");
34+ q.removeQueryItem("oauth_signature_method");
35+ q.removeQueryItem("oauth_version");
36+ q.removeQueryItem("oauth_signature");
37+ u.setQuery(q);
38+ return u;
39+}
40+
41+class AudioComparer : public QObject
42+{
43+ Q_OBJECT
44+public:
45+ Q_INVOKABLE bool compare(const QUrl &url1, const QUrl &url2)
46+ {
47+ return oauthCleanedUrl(url1) == oauthCleanedUrl(url2);
48+ }
49+};
50+
51+static QObject *audio_comparer_singleton_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
52+{
53+ Q_UNUSED(engine)
54+ Q_UNUSED(scriptEngine)
55+
56+ return new AudioComparer();
57+}
2658
2759void DashPlugin::registerTypes(const char *uri)
2860{
@@ -32,4 +64,7 @@ void DashPlugin::registerTypes(const char *uri)
3264 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
3365 qmlRegisterType<OrganicGrid>(uri, 0, 1, "OrganicGrid");
3466 qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");
67+ qmlRegisterSingletonType<AudioComparer>(uri, 0, 1, "AudioUrlComparer", audio_comparer_singleton_provider);
3568}
69+
70+#include "plugin.moc"
plugins/Dash/qmldir+3
@@ -2,6 +2,9 @@ module Dash
22plugin Dash-qml
33typeinfo Dash.qmltypes
44singleton CardCreatorCache 0.1 CardCreatorCache.qml
5+singleton DashAudioPlayer 0.1 DashAudioPlayer.qml
56ScopeStyle 0.1 ScopeStyle.qml
67CardAttributes 0.1 CardAttributes.qml
78CroppedImageMinimumSourceSize 0.1 CroppedImageMinimumSourceSize.qml
9+AudioProgressBar 0.1 AudioProgressBar.qml
10+CardAudioProgress 0.1 CardAudioProgress.qml
plugins/LightDM/CMakeLists.txt+2
@@ -1,4 +1,5 @@
11pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
2+pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-3)
23
34find_package(Qt5Core REQUIRED)
45find_package(Qt5Quick REQUIRED)
@@ -7,6 +8,7 @@ include_directories(
78 ${CMAKE_CURRENT_SOURCE_DIR}
89 ${CMAKE_CURRENT_BINARY_DIR}
910 ${CMAKE_SOURCE_DIR}/plugins/Utils
11+ ${CMAKE_BINARY_DIR}/tests/mocks/LightDM/IntegratedLightDM
1012 ${LIBLIGHTDM_INCLUDE_DIRS}
1113 ${libunity8-private_SOURCE_DIR}
1214 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
plugins/LightDM/FullLightDM/CMakeLists.txt+1−7
@@ -2,15 +2,9 @@ pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-3)
22
33set(PLUGIN_CLASSNAME "FullLightDM")
44
5−# Written to source dir as thats where add_unity8_plugin expects it
6−configure_file(../qmldir.in ${CMAKE_CURRENT_SOURCE_DIR}/qmldir)
7−
85add_definitions(-DFULL_LIGHTDM)
96
10−include_directories(
11− ${LIBLIGHTDM_INCLUDE_DIRS}
12− ${CMAKE_CURRENT_BINARY_DIR}
13−)
7+include_directories(../)
148
159foreach(source_file ${QMLPLUGIN_SRC})
1610 list(APPEND RELATIVE_QMLPLUGIN_SRC ../${source_file})
plugins/LightDM/FullLightDM/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module LightDM.FullLightDM
2+plugin FullLightDM-qml
3+typeinfo FullLightDM.qmltypes
plugins/LightDM/IntegratedLightDM/CMakeLists.txt+5−5
@@ -1,14 +1,14 @@
11set(PLUGIN_CLASSNAME "IntegratedLightDM")
22
3−# Written to source dir as thats where add_unity8_plugin expects it
4−configure_file(../qmldir.in ${CMAKE_CURRENT_SOURCE_DIR}/qmldir)
5−
63add_definitions(-DINTEGRATED_LIGHTDM)
74
5+foreach(include_directory ${QMLPLUGIN_INCLUDES})
6+ list(APPEND RELATIVE_QMLPLUGIN_INCLUDES ../${include_directory})
7+endforeach()
8+
89include_directories(
10+ ../
911 ${libunity8-private_SOURCE_DIR}
10− ${CMAKE_SOURCE_DIR}/tests/mocks/LightDM/IntegratedLightDM
11− ${CMAKE_BINARY_DIR}/tests/mocks/LightDM/IntegratedLightDM
1212)
1313
1414foreach(source_file ${QMLPLUGIN_SRC})
plugins/LightDM/IntegratedLightDM/liblightdm/CMakeLists.txt+3
@@ -15,14 +15,17 @@ add_library(MockLightDM-demo-shared SHARED ${LibLightDM_SOURCES})
1515
1616include_directories(
1717 ${CMAKE_CURRENT_BINARY_DIR}
18+ ${GLIB_INCLUDE_DIRS}
1819 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
1920)
2021
2122target_link_libraries(integratedLightDM
23+ ${GLIB_LIBRARIES}
2224 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
2325 -lpam
2426)
2527target_link_libraries(MockLightDM-demo-shared
28+ ${GLIB_LIBRARIES}
2629 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
2730 -lpam
2831)
plugins/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+23−7
@@ -18,6 +18,7 @@
1818
1919#include "UsersModelPrivate.h"
2020
21+#include <glib.h>
2122#include <QDir>
2223#include <QSettings>
2324#include <QStringList>
@@ -28,14 +29,29 @@ namespace QLightDM
2829UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
2930 : q_ptr(parent)
3031{
31− QSettings settings(QDir::homePath() + "/.unity8-greeter-demo", QSettings::NativeFormat);
32− QStringList users = settings.value(QStringLiteral("users"), QStringList() << qgetenv("USER")).toStringList();
32+ QFileInfo demoFile(QDir::homePath() + "/.unity8-greeter-demo");
33+ QString currentUser = g_get_user_name();
3334
34− entries.reserve(users.count());
35− Q_FOREACH(const QString &user, users)
36− {
37− QString name = settings.value(user + "/name", user).toString();
38− entries.append({user, name, 0, 0, false, false, 0, 0});
35+ if (demoFile.exists()) {
36+ QSettings settings(demoFile.filePath(), QSettings::NativeFormat);
37+ QStringList users = settings.value(QStringLiteral("users"), QStringList() << currentUser).toStringList();
38+
39+ entries.reserve(users.count());
40+ Q_FOREACH(const QString &user, users)
41+ {
42+ QString name = settings.value(user + "/name", user).toString();
43+ entries.append({user, name, 0, 0, false, false, 0, 0});
44+ }
45+ } else {
46+ // If we were using the actual liblightdm, we could just ask it
47+ // for the user's real name. But we aren't. We *should* ask
48+ // AccountsService for the real name, like liblightdm does internally,
49+ // but this is close enough since AS and passwd are always in sync.
50+ QString realName = QString::fromUtf8(g_get_real_name()); // gets name from passwd entry
51+ if (realName == QStringLiteral("Unknown")) { // glib doesn't translate this string
52+ realName.clear();
53+ }
54+ entries.append({currentUser, realName, 0, 0, false, false, 0, 0});
3955 }
4056}
4157
plugins/LightDM/IntegratedLightDM/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module LightDM.IntegratedLightDM
2+plugin IntegratedLightDM-qml
3+typeinfo IntegratedLightDM.qmltypes
plugins/LightDM/qmldir.indeleted−3
@@ -1,3 +0,0 @@
1−module LightDM.@PLUGIN_CLASSNAME@
2−plugin @PLUGIN_CLASSNAME@-qml
3−typeinfo @PLUGIN_CLASSNAME@.qmltypes
plugins/Powerd/CMakeLists.txt−2
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
31include_directories(
42 ${GIO_INCLUDE_DIRS}
53)
plugins/UInput/CMakeLists.txtnew file+7
@@ -0,0 +1,7 @@
1+add_library(UInput-qml MODULE
2+ plugin.cpp
3+ uinput.cpp
4+)
5+
6+qt5_use_modules(UInput-qml Qml)
7+add_unity8_plugin(UInput 0.1 UInput TARGETS UInput-qml)
plugins/UInput/UInput.qmltypesnew file+44
@@ -0,0 +1,44 @@
1+import QtQuick.tooling 1.1
2+
3+// This file describes the plugin-supplied types contained in the library.
4+// It is used for QML tooling purposes only.
5+//
6+// This file was auto-generated by:
7+// 'qmlplugindump -notrelocatable UInput 0.1 plugins'
8+
9+Module {
10+ Component {
11+ name: "UInput"
12+ prototype: "QObject"
13+ exports: ["UInput/UInput 0.1"]
14+ exportMetaObjectRevisions: [0]
15+ Enum {
16+ name: "Button"
17+ values: {
18+ "ButtonLeft": 0,
19+ "ButtonRight": 1,
20+ "ButtonMiddle": 2
21+ }
22+ }
23+ Method { name: "createMouse" }
24+ Method { name: "removeMouse" }
25+ Method {
26+ name: "moveMouse"
27+ Parameter { name: "dx"; type: "int" }
28+ Parameter { name: "dy"; type: "int" }
29+ }
30+ Method {
31+ name: "pressMouse"
32+ Parameter { name: "button"; type: "Button" }
33+ }
34+ Method {
35+ name: "releaseMouse"
36+ Parameter { name: "button"; type: "Button" }
37+ }
38+ Method {
39+ name: "scrollMouse"
40+ Parameter { name: "dh"; type: "int" }
41+ Parameter { name: "dv"; type: "int" }
42+ }
43+ }
44+}
plugins/UInput/plugin.cppnew file+26
@@ -0,0 +1,26 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "uinput.h"
19+
20+#include <QtQml/qqml.h>
21+
22+void UInputPlugin::registerTypes(const char *uri)
23+{
24+ Q_ASSERT(uri == QLatin1String("UInput"));
25+ qmlRegisterType<UInput>(uri, 0, 1, "UInput");
26+}
plugins/UInput/plugin.hnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UINPUT_PLUGIN_H
18+#define UINPUT_PLUGIN_H
19+
20+#include <QtQml/QQmlEngine>
21+#include <QtQml/QQmlExtensionPlugin>
22+
23+class UInputPlugin : public QQmlExtensionPlugin
24+{
25+ Q_OBJECT
26+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
27+
28+public:
29+ void registerTypes(const char *uri) override;
30+};
31+
32+#endif
plugins/UInput/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module UInput
2+plugin UInput-qml
3+typeinfo UInput.qmltypes
plugins/UInput/uinput.cppnew file+182
@@ -0,0 +1,182 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "uinput.h"
18+
19+#include <QFile>
20+#include <QDebug>
21+#include <QDateTime>
22+
23+#include <unistd.h>
24+#include <time.h>
25+
26+UInput::UInput(QObject *parent) :
27+ QObject(parent)
28+{
29+ m_devName = QByteArrayLiteral("unity8-simulated-mouse");
30+ m_uinput.setFileName(QStringLiteral("/dev/uinput"));
31+
32+ memset(&m_uinput_mouse_dev, 0, sizeof(m_uinput_mouse_dev));
33+ m_uinput_mouse_dev.id.bustype = BUS_USB;
34+ m_uinput_mouse_dev.id.version = 1;
35+ strncpy(m_uinput_mouse_dev.name, m_devName.constData(), m_devName.length());
36+}
37+
38+UInput::~UInput()
39+{
40+ if (m_mouseCreated) {
41+ removeMouse();
42+ }
43+}
44+
45+void UInput::createMouse()
46+{
47+ if (m_mouseCreated) {
48+ qDebug() << "Already have a virtual device. Not creating another one.";
49+ return;
50+ }
51+
52+ if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
53+ return;
54+ }
55+
56+ ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_REL);
57+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_X);
58+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_Y);
59+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_HWHEEL);
60+ ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_WHEEL);
61+
62+ ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_KEY);
63+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MOUSE);
64+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_LEFT);
65+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MIDDLE);
66+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_RIGHT);
67+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_FORWARD);
68+ ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_BACK);
69+
70+ ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_SYN);
71+
72+ int len = write(m_uinput.handle(), &m_uinput_mouse_dev, sizeof(m_uinput_mouse_dev));
73+ if (len <= 0) {
74+ qWarning() << "Failed to write to uinput. Cannot create virtual uinput mouse.";
75+ return;
76+ }
77+
78+ int err = ioctl(m_uinput.handle(), UI_DEV_CREATE);
79+ if (err != 0) {
80+ qWarning() << "Cannot create virtual uinput device. Create ioctl failed:" << err;
81+ return;
82+ }
83+ m_mouseCreated = true;
84+ qDebug() << "Virtual uinput mouse device created.";
85+}
86+
87+void UInput::removeMouse()
88+{
89+ if (!m_mouseCreated) {
90+ return;
91+ }
92+
93+ if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
94+ qWarning() << "cannot open uinput... ";
95+ return;
96+ }
97+
98+ int err = ioctl(m_uinput.handle(), UI_DEV_DESTROY);
99+ if (err != 0) {
100+ qWarning() << "Failed to destroy virtual uinput device. Destroy ioctl failed:" << err;
101+ } else {
102+ qDebug() << "Virtual uinput mouse device removed.";
103+ }
104+ m_uinput.close();
105+ m_mouseCreated = false;
106+}
107+
108+void UInput::moveMouse(int dx, int dy)
109+{
110+ struct input_event event;
111+ memset(&event, 0, sizeof(event));
112+ clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
113+ event.type = EV_REL;
114+ event.code = REL_X;
115+ event.value = dx;
116+ write(m_uinput.handle(), &event, sizeof(event));
117+
118+ event.code = REL_Y;
119+ event.value = dy;
120+ write(m_uinput.handle(), &event, sizeof(event));
121+
122+ event.type = EV_SYN;
123+ event.code = SYN_REPORT;
124+ event.value = 0;
125+ write(m_uinput.handle(), &event, sizeof(event));
126+}
127+
128+void UInput::pressMouse(Button button)
129+{
130+ injectMouse(button, 1);
131+}
132+
133+void UInput::releaseMouse(Button button)
134+{
135+ injectMouse(button, 0);
136+}
137+
138+void UInput::scrollMouse(int dh, int dv)
139+{
140+ struct input_event event;
141+ memset(&event, 0, sizeof(event));
142+ clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
143+ event.type = EV_REL;
144+ event.code = REL_HWHEEL;
145+ event.value = dh;
146+ write(m_uinput.handle(), &event, sizeof(event));
147+
148+ event.code = REL_WHEEL;
149+ event.value = dv;
150+ write(m_uinput.handle(), &event, sizeof(event));
151+
152+ event.type = EV_SYN;
153+ event.code = SYN_REPORT;
154+ event.value = 0;
155+ write(m_uinput.handle(), &event, sizeof(event));
156+}
157+
158+void UInput::injectMouse(Button button, int down)
159+{
160+ struct input_event event;
161+ memset(&event, 0, sizeof(event));
162+ clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
163+ event.type = EV_KEY;
164+ switch (button) {
165+ case ButtonLeft:
166+ event.code = BTN_LEFT;
167+ break;
168+ case ButtonRight:
169+ event.code = BTN_RIGHT;
170+ break;
171+ case ButtonMiddle:
172+ event.code = BTN_MIDDLE;
173+ break;
174+ }
175+ event.value = down;
176+ write(m_uinput.handle(), &event, sizeof(event));
177+
178+ event.type = EV_SYN;
179+ event.code = SYN_REPORT;
180+ event.value = 0;
181+ write(m_uinput.handle(), &event, sizeof(event));
182+}
plugins/UInput/uinput.hnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+
18+#ifndef UINPUT_H
19+#define UINPUT_H
20+
21+#include <QObject>
22+#include <QFile>
23+
24+#include <linux/uinput.h>
25+
26+
27+class UInput : public QObject
28+{
29+ Q_OBJECT
30+ Q_ENUMS(Button)
31+
32+public:
33+ enum Button {
34+ ButtonLeft,
35+ ButtonRight,
36+ ButtonMiddle
37+ };
38+
39+ explicit UInput(QObject *parent = nullptr);
40+ ~UInput();
41+
42+ Q_INVOKABLE void createMouse();
43+ Q_INVOKABLE void removeMouse();
44+
45+ Q_INVOKABLE void moveMouse(int dx, int dy);
46+ Q_INVOKABLE void pressMouse(Button button);
47+ Q_INVOKABLE void releaseMouse(Button button);
48+ Q_INVOKABLE void scrollMouse(int dh, int dv);
49+
50+private:
51+ void injectMouse(Button button, int down);
52+
53+private:
54+ QFile m_uinput;
55+ uinput_user_dev m_uinput_mouse_dev;
56+ QByteArray m_devName;
57+
58+ bool m_mouseCreated = false;
59+};
60+
61+#endif // UINPUT_H
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+8−2
@@ -715,8 +715,14 @@ void DirectionalDragArea::itemChange(ItemChange change, const ItemChangeData &va
715715 value.window->installEventFilter(TouchRegistry::instance());
716716
717717 // TODO: Handle window->screen() changes (ie window changing screens)
718− qreal pixelsPerMm = value.window->screen()->physicalDotsPerInch() / 25.4;
719− d->setPixelsPerMm(pixelsPerMm);
718+
719+ qreal pixelsPerInch = value.window->screen()->physicalDotsPerInch();
720+ if (pixelsPerInch < 0) {
721+ // It can return garbage when run in a XVFB server (Virtual Framebuffer 'fake' X server)
722+ pixelsPerInch = 72;
723+ }
724+
725+ d->setPixelsPerMm(pixelsPerInch / 25.4);
720726 }
721727 }
722728}
plugins/Unity/DashCommunicator/dashcommunicator.cpp+6
@@ -27,6 +27,12 @@ DashCommunicator::DashCommunicator(QObject *parent):
2727 start();
2828}
2929
30+DashCommunicator::~DashCommunicator()
31+{
32+ quit();
33+ wait();
34+}
35+
3036void DashCommunicator::setCurrentScope(int index, bool animate, bool isSwipe)
3137{
3238 m_mutex.lock();
plugins/Unity/DashCommunicator/dashcommunicator.h+1−1
@@ -28,7 +28,7 @@ class DashCommunicator: public QThread
2828 Q_OBJECT
2929public:
3030 explicit DashCommunicator(QObject *parent = 0);
31− ~DashCommunicator() = default;
31+ ~DashCommunicator();
3232
3333public Q_SLOTS:
3434 void setCurrentScope(int index, bool animate, bool isSwipe);
plugins/Unity/Indicators/CMakeLists.txt−4
@@ -1,9 +1,5 @@
11project(IndicatorsQml)
22
3−pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
4−pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
5−pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
6−
73find_package(Qt5Core REQUIRED)
84find_package(Qt5Quick REQUIRED)
95
plugins/Unity/Indicators/modelactionrootstate.cpp+76−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -32,6 +32,7 @@ extern "C" {
3232ModelActionRootState::ModelActionRootState(QObject *parent)
3333 : RootStateObject(parent),
3434 m_menu(nullptr)
35+ , m_reentryGuard(false)
3536{
3637}
3738
@@ -62,6 +63,7 @@ void ModelActionRootState::setMenu(UnityMenuModel* menu)
6263 connect(m_menu, &UnityMenuModel::destroyed, this, &ModelActionRootState::reset);
6364 }
6465 updateActionState();
66+ updateOtherActions();
6567 Q_EMIT menuChanged();
6668
6769 if (wasValid != valid())
@@ -69,6 +71,21 @@ void ModelActionRootState::setMenu(UnityMenuModel* menu)
6971 }
7072}
7173
74+QString ModelActionRootState::secondaryAction() const
75+{
76+ return m_secondaryAction;
77+}
78+
79+QString ModelActionRootState::scrollAction() const
80+{
81+ return m_scrollAction;
82+}
83+
84+QString ModelActionRootState::submenuAction() const
85+{
86+ return m_submenuAction;
87+}
88+
7289bool ModelActionRootState::valid() const
7390{
7491 return !currentState().empty();
@@ -79,6 +96,7 @@ void ModelActionRootState::onModelRowsAdded(const QModelIndex& parent, int start
7996 Q_UNUSED(parent);
8097 if (start == 0 && end >= 0) {
8198 updateActionState();
99+ updateOtherActions();
82100 }
83101}
84102
@@ -87,6 +105,7 @@ void ModelActionRootState::onModelRowsRemoved(const QModelIndex& parent, int sta
87105 Q_UNUSED(parent);
88106 if (start == 0 && end >= 0) {
89107 updateActionState();
108+ updateOtherActions();
90109 }
91110}
92111
@@ -99,6 +118,7 @@ void ModelActionRootState::onModelDataChanged(const QModelIndex& topLeft, const
99118
100119 if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
101120 updateActionState();
121+ updateOtherActions();
102122 }
103123}
104124
@@ -108,10 +128,15 @@ void ModelActionRootState::reset()
108128
109129 Q_EMIT menuChanged();
110130 setCurrentState(QVariantMap());
131+
132+ updateOtherActions();
111133}
112134
113135void ModelActionRootState::updateActionState()
114136{
137+ if (m_reentryGuard) return;
138+ m_reentryGuard = true;
139+
115140 if (m_menu && m_menu->rowCount() > 0) {
116141 ActionStateParser* oldParser = m_menu->actionStateParser();
117142 m_menu->setActionStateParser(&m_parser);
@@ -126,4 +151,54 @@ void ModelActionRootState::updateActionState()
126151 }
127152 // else if m_menu->rowCount() == 0, let's leave existing cache in place
128153 // until the new menu comes in, to avoid flashing the UI empty for a moment
154+
155+ m_reentryGuard = false;
156+}
157+
158+void ModelActionRootState::updateOtherActions()
159+{
160+ if (m_reentryGuard) return;
161+ m_reentryGuard = true;
162+
163+ if (m_menu && m_menu->rowCount() > 0) {
164+ QVariantMap map;
165+ map[QStringLiteral("submenu-action")] = QStringLiteral("string");
166+ map[QStringLiteral("x-canonical-scroll-action")] = QStringLiteral("string");
167+ map[QStringLiteral("x-canonical-secondary-action")] = QStringLiteral("string");
168+ m_menu->loadExtendedAttributes(0, map);
169+ QVariantMap extMap = m_menu->get(0, "ext").toMap();
170+
171+ QString secondaryAction = extMap.value(QStringLiteral("xCanonicalSecondaryAction")).toString();
172+ if (m_secondaryAction != secondaryAction) {
173+ m_secondaryAction = secondaryAction;
174+ Q_EMIT secondaryActionChanged();
175+ }
176+
177+ QString scrollAction = extMap.value(QStringLiteral("xCanonicalScrollAction")).toString();
178+ if (m_scrollAction != scrollAction) {
179+ m_scrollAction = scrollAction;
180+ Q_EMIT scrollActionChanged();
181+ }
182+
183+ QString submenuAction = extMap.value(QStringLiteral("submenuAction")).toString();
184+ if (m_submenuAction != submenuAction) {
185+ m_submenuAction = submenuAction;
186+ Q_EMIT submenuActionChanged();
187+ }
188+ } else {
189+ if (!m_secondaryAction.isEmpty()) {
190+ m_secondaryAction.clear();
191+ Q_EMIT secondaryActionChanged();
192+ }
193+ if (!m_scrollAction.isEmpty()) {
194+ m_scrollAction.clear();
195+ Q_EMIT scrollActionChanged();
196+ }
197+ if (!m_submenuAction.isEmpty()) {
198+ m_submenuAction.clear();
199+ Q_EMIT submenuActionChanged();
200+ }
201+ }
202+
203+ m_reentryGuard = false;
129204}
plugins/Unity/Indicators/modelactionrootstate.h+15−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -30,6 +30,9 @@ class UNITYINDICATORS_EXPORT ModelActionRootState : public RootStateObject
3030{
3131 Q_OBJECT
3232 Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
33+ Q_PROPERTY(QString secondaryAction READ secondaryAction NOTIFY secondaryActionChanged)
34+ Q_PROPERTY(QString scrollAction READ scrollAction NOTIFY scrollActionChanged)
35+ Q_PROPERTY(QString submenuAction READ submenuAction NOTIFY submenuActionChanged)
3336public:
3437 ModelActionRootState(QObject *parent = 0);
3538 virtual ~ModelActionRootState();
@@ -37,14 +40,17 @@ public:
3740 UnityMenuModel* menu() const;
3841 void setMenu(UnityMenuModel* menu);
3942
40− int index() const;
41− void setIndex(int index);
43+ QString secondaryAction() const;
44+ QString scrollAction() const;
45+ QString submenuAction() const;
4246
4347 bool valid() const override;
4448
4549Q_SIGNALS:
4650 void menuChanged();
47− void indexChanged();
51+ void secondaryActionChanged();
52+ void scrollActionChanged();
53+ void submenuActionChanged();
4854
4955private Q_SLOTS:
5056 void onModelRowsAdded(const QModelIndex& parent, int start, int end);
@@ -54,8 +60,13 @@ private Q_SLOTS:
5460
5561private:
5662 void updateActionState();
63+ void updateOtherActions();
5764
5865 UnityMenuModel* m_menu;
66+ QString m_secondaryAction;
67+ QString m_scrollAction;
68+ QString m_submenuAction;
69+ bool m_reentryGuard;
5970};
6071
6172#endif // MODELACTIONROOTSTATE_H
plugins/Unity/Session/CMakeLists.txt−2
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
31include_directories(
42 ${CMAKE_CURRENT_SOURCE_DIR}
53 ${CMAKE_CURRENT_BINARY_DIR}
plugins/Utils/CMakeLists.txt+2−3
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
31include_directories(
42 ${CMAKE_CURRENT_SOURCE_DIR}
53 ${CMAKE_CURRENT_BINARY_DIR}
@@ -13,7 +11,7 @@ set(QMLPLUGIN_SRC
1311 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
1412 applicationsfiltermodel.cpp
1513 constants.cpp
16− HomeKeyWatcher.cpp
14+ WindowInputMonitor.cpp
1715 inputwatcher.cpp
1816 qlimitproxymodelqml.cpp
1917 unitysortfilterproxymodelqml.cpp
@@ -24,6 +22,7 @@ set(QMLPLUGIN_SRC
2422 easingcurve.cpp
2523 windowstatestorage.cpp
2624 timezoneFormatter.cpp
25+ inputeventgenerator.cpp
2726 plugin.cpp
2827 )
2928
plugins/Utils/EdgeBarrierSettings.qml+1−1
@@ -35,7 +35,7 @@ QtObject {
3535
3636 property Timer printSettingsTimer: Timer {
3737 interval: 1
38− onTriggered: printSettings();
38+ onTriggered: d.printSettings();
3939 }
4040 function printSettings() {
4141 console.log("EdgeBarrierSettings: min="+(minPushThreshold/units.gu(1))+"gu("+minPushThreshold+"px)"
plugins/Utils/HomeKeyWatcher.hdeleted−74
@@ -1,74 +0,0 @@
1−/*
2− * Copyright (C) 2015 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#ifndef UNITY_HOMEKEYWATCHER_H
18−#define UNITY_HOMEKEYWATCHER_H
19−
20−#include <QQuickItem>
21−#include <QPointer>
22−
23−#include "Timer.h"
24−#include "ElapsedTimer.h"
25−
26−/*
27− Signals when the home key seems to be have been intentionally tapped.
28−
29− It only says the home key has been activated if it has been tapped in isolation,
30− that is, without being accompanied by touches on the screen. Home key taps that
31− happen along with (or immediately after, or immediately before) touches on the
32− screen are considered to have happened unintentionally and are thus ignored.
33−
34− Rationale being that it's easy to accidentally hit the home key while performing
35− a swipe from a screen edge, for instance. That's particularly the case when the
36− home key is a capacitive key.
37− */
38−class HomeKeyWatcher : public QQuickItem
39−{
40− Q_OBJECT
41−public:
42−
43− HomeKeyWatcher(QQuickItem *parent = 0);
44−
45− // for testing
46− HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
47− UnityUtil::AbstractElapsedTimer *elapsedTimer,
48− QQuickItem *parent = 0);
49−
50− virtual ~HomeKeyWatcher();
51−
52− bool eventFilter(QObject *watched, QEvent *event) override;
53−
54− void update(QEvent *event);
55−
56− const qint64 msecsWithoutTouches = 150;
57−
58−Q_SIGNALS:
59− // Emitted when the home key has been intentionally tapped
60− void activated();
61−
62−private Q_SLOTS:
63− void setupFilterOnWindow(QQuickWindow *window);
64− void emitActivatedIfNoTouchesAround();
65−
66−private:
67− QPointer<QQuickWindow> m_filteredWindow;
68− bool m_windowBeingTouched;
69− bool m_homeKeyPressed;
70− UnityUtil::AbstractElapsedTimer *m_windowLastTouchedTimer;
71− UnityUtil::AbstractTimer *m_activationTimer;
72−};
73−
74−#endif // UNITY_HOMEKEYWATCHER_H
plugins/Utils/HomeKeyWatcher.cpp → plugins/Utils/WindowInputMonitor.cpprenamed+19−12
@@ -14,18 +14,18 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−#include "HomeKeyWatcher.h"
17+#include "WindowInputMonitor.h"
1818
1919#include <QQuickWindow>
2020
2121using namespace UnityUtil;
2222
23−HomeKeyWatcher::HomeKeyWatcher(QQuickItem *parent)
24− : HomeKeyWatcher(new Timer, new ElapsedTimer, parent)
23+WindowInputMonitor::WindowInputMonitor(QQuickItem *parent)
24+ : WindowInputMonitor(new Timer, new ElapsedTimer, parent)
2525{
2626}
2727
28−HomeKeyWatcher::HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
28+WindowInputMonitor::WindowInputMonitor(UnityUtil::AbstractTimer *timer,
2929 UnityUtil::AbstractElapsedTimer *elapsedTimer,
3030 QQuickItem *parent)
3131 : QQuickItem(parent)
@@ -37,20 +37,20 @@ HomeKeyWatcher::HomeKeyWatcher(UnityUtil::AbstractTimer *timer,
3737 m_windowLastTouchedTimer->start();
3838
3939 connect(this, &QQuickItem::windowChanged,
40− this, &HomeKeyWatcher::setupFilterOnWindow);
40+ this, &WindowInputMonitor::setupFilterOnWindow);
4141
4242 connect(m_activationTimer, &UnityUtil::AbstractTimer::timeout,
43− this, &HomeKeyWatcher::emitActivatedIfNoTouchesAround);
43+ this, &WindowInputMonitor::emitActivatedIfNoTouchesAround);
4444 m_activationTimer->setInterval(msecsWithoutTouches);
4545}
4646
47−HomeKeyWatcher::~HomeKeyWatcher()
47+WindowInputMonitor::~WindowInputMonitor()
4848{
4949 delete m_windowLastTouchedTimer;
5050 delete m_activationTimer;
5151}
5252
53−bool HomeKeyWatcher::eventFilter(QObject *watched, QEvent *event)
53+bool WindowInputMonitor::eventFilter(QObject *watched, QEvent *event)
5454{
5555 Q_ASSERT(!m_filteredWindow.isNull());
5656 Q_ASSERT(watched == static_cast<QObject*>(m_filteredWindow.data()));
@@ -62,7 +62,7 @@ bool HomeKeyWatcher::eventFilter(QObject *watched, QEvent *event)
6262 return false;
6363}
6464
65−void HomeKeyWatcher::update(QEvent *event)
65+void WindowInputMonitor::update(QEvent *event)
6666{
6767 if (event->type() == QEvent::KeyPress) {
6868 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
@@ -86,15 +86,22 @@ void HomeKeyWatcher::update(QEvent *event)
8686
8787 m_activationTimer->stop();
8888 m_windowBeingTouched = true;
89+ Q_EMIT touchBegun();
8990
9091 } else if (event->type() == QEvent::TouchEnd) {
9192
9293 m_windowBeingTouched = false;
9394 m_windowLastTouchedTimer->start();
95+
96+ QTouchEvent * touchEv = static_cast<QTouchEvent *>(event);
97+ if (touchEv && !touchEv->touchPoints().isEmpty()) {
98+ const QPointF pos = touchEv->touchPoints().last().screenPos();
99+ Q_EMIT touchEnded(pos);
100+ }
94101 }
95102}
96103
97−void HomeKeyWatcher::setupFilterOnWindow(QQuickWindow *window)
104+void WindowInputMonitor::setupFilterOnWindow(QQuickWindow *window)
98105{
99106 if (!m_filteredWindow.isNull()) {
100107 m_filteredWindow->removeEventFilter(this);
@@ -107,10 +114,10 @@ void HomeKeyWatcher::setupFilterOnWindow(QQuickWindow *window)
107114 }
108115}
109116
110−void HomeKeyWatcher::emitActivatedIfNoTouchesAround()
117+void WindowInputMonitor::emitActivatedIfNoTouchesAround()
111118{
112119 if (!m_homeKeyPressed && !m_windowBeingTouched &&
113120 (m_windowLastTouchedTimer->elapsed() > msecsWithoutTouches)) {
114− Q_EMIT activated();
121+ Q_EMIT homeKeyActivated();
115122 }
116123}
plugins/Utils/WindowInputMonitor.hnew file+91
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UNITY_WINDOWINPUTMONITOR_H
18+#define UNITY_WINDOWINPUTMONITOR_H
19+
20+#include <QQuickItem>
21+#include <QPointer>
22+
23+#include "Timer.h"
24+#include "ElapsedTimer.h"
25+
26+/**
27+ * Monitors input events received by the window holding this item and the Home (Win aka Super_L)
28+ * key presses.
29+ *
30+ * Additionally, this class monitors for generic touch events on the screen, to
31+ * help with hiding/revealing the mouse pointer.
32+ */
33+class WindowInputMonitor : public QQuickItem
34+{
35+ Q_OBJECT
36+public:
37+
38+ WindowInputMonitor(QQuickItem *parent = 0);
39+
40+ // for testing
41+ WindowInputMonitor(UnityUtil::AbstractTimer *timer,
42+ UnityUtil::AbstractElapsedTimer *elapsedTimer,
43+ QQuickItem *parent = 0);
44+
45+ virtual ~WindowInputMonitor();
46+
47+ bool eventFilter(QObject *watched, QEvent *event) override;
48+
49+ void update(QEvent *event);
50+
51+ const qint64 msecsWithoutTouches = 150;
52+
53+Q_SIGNALS:
54+ /**
55+ * Emitted when the home key has been intentionally tapped
56+ *
57+ * It only says the home key has been activated if it has been tapped in isolation,
58+ * that is, without being accompanied by touches on the screen. Home key taps that
59+ * happen along with (or immediately after, or immediately before) touches on the
60+ * screen are considered to have happened unintentionally and are thus ignored.
61+ *
62+ * Rationale being that it's easy to accidentally hit the home key while performing
63+ * a swipe from a screen edge, for instance. That's particularly the case when the
64+ * home key is a capacitive key.
65+ */
66+ void homeKeyActivated();
67+
68+ /**
69+ * Emitted when a touch begin event is detected
70+ */
71+ void touchBegun();
72+
73+ /**
74+ * Emitted when a touch end event is detected
75+ * @param pos the position in screen coordinates
76+ */
77+ void touchEnded(const QPointF &pos);
78+
79+private Q_SLOTS:
80+ void setupFilterOnWindow(QQuickWindow *window);
81+ void emitActivatedIfNoTouchesAround();
82+
83+private:
84+ QPointer<QQuickWindow> m_filteredWindow;
85+ bool m_windowBeingTouched;
86+ bool m_homeKeyPressed;
87+ UnityUtil::AbstractElapsedTimer *m_windowLastTouchedTimer;
88+ UnityUtil::AbstractTimer *m_activationTimer;
89+};
90+
91+#endif // UNITY_WINDOWINPUTMONITOR_H
plugins/Utils/inputeventgenerator.cppnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "inputeventgenerator.h"
18+
19+#include <QQuickWindow>
20+#include <QDebug>
21+#include <QDateTime>
22+
23+InputEventGenerator::InputEventGenerator(QQuickItem *parent)
24+ : QQuickItem(parent)
25+{
26+}
27+
28+void InputEventGenerator::generateKeyEvent(Qt::Key key, bool pressed, Qt::KeyboardModifiers modifiers, quint64 timestamp, quint32 nativeScanCode, const QString &text)
29+{
30+ QEvent::Type type = pressed ? QEvent::KeyPress : QEvent::KeyRelease;
31+ QKeyEvent ev(type, key, modifiers, nativeScanCode, 0, 0, text);
32+ ev.setTimestamp(timestamp);
33+ QCoreApplication::sendEvent(window(), &ev);
34+}
plugins/Utils/inputeventgenerator.hnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef INPUTEVENTGENERATOR_H
18+#define INPUTEVENTGENERATOR_H
19+
20+#include <QQuickItem>
21+#include <QPointer>
22+#include <QDateTime>
23+
24+/**
25+ * \brief This class allows injecting Key events into the scene it lives in.
26+ */
27+class InputEventGenerator : public QQuickItem
28+{
29+ Q_OBJECT
30+public:
31+ InputEventGenerator(QQuickItem *parent = 0);
32+
33+ /**
34+ * Generate and post and event to the scene. The key event will be sent to the scene the Generator
35+ * lives in and it will be dispatched through the regular event/focus queue.
36+ */
37+ Q_INVOKABLE void generateKeyEvent(Qt::Key key, bool pressed, Qt::KeyboardModifiers modifiers = Qt::NoModifier, quint64 timestamp = QDateTime::currentMSecsSinceEpoch(), quint32 nativeScanCode = 0, const QString &text = QString());
38+};
39+
40+#endif // INPUTEVENTGENERATOR_H
plugins/Utils/plugin.cpp+4−2
@@ -25,7 +25,7 @@
2525// local
2626#include "activefocuslogger.h"
2727#include "easingcurve.h"
28−#include "HomeKeyWatcher.h"
28+#include "WindowInputMonitor.h"
2929#include "inputwatcher.h"
3030#include "qlimitproxymodelqml.h"
3131#include "unitysortfilterproxymodelqml.h"
@@ -36,6 +36,7 @@
3636#include "constants.h"
3737#include "timezoneFormatter.h"
3838#include "applicationsfiltermodel.h"
39+#include "inputeventgenerator.h"
3940
4041static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
4142{
@@ -54,7 +55,7 @@ static QObject *createConstants(QQmlEngine *engine, QJSEngine *scriptEngine)
5455void UtilsPlugin::registerTypes(const char *uri)
5556{
5657 Q_ASSERT(uri == QLatin1String("Utils"));
57− qmlRegisterType<HomeKeyWatcher>(uri, 0, 1, "HomeKeyWatcher");
58+ qmlRegisterType<WindowInputMonitor>(uri, 0, 1, "WindowInputMonitor");
5859 qmlRegisterType<QAbstractItemModel>();
5960 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
6061 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
@@ -68,6 +69,7 @@ void UtilsPlugin::registerTypes(const char *uri)
6869 [](QQmlEngine*, QJSEngine*) -> QObject* { return new TimezoneFormatter; });
6970 qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
7071 qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel");
72+ qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator");
7173}
7274
7375void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
po/aa.ponew file+667
@@ -0,0 +1,667 @@
1+# Afar translation for unity8
2+# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2016-02-16 03:29+0000\n"
11+"PO-Revision-Date: 2016-02-12 10:18+0000\n"
12+"Last-Translator: Charif AYFARAH <ayfarah@ymail.com>\n"
13+"Language-Team: Afar <aa@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
19+"X-Generator: Launchpad (build 17925)\n"
20+
21+#: plugins/IntegratedLightDM/Greeter.cpp:112
22+msgid "Password: "
23+msgstr "Cuumita "
24+
25+#: plugins/Unity/Launcher/launcheritem.cpp:47
26+#: plugins/Unity/Launcher/launcheritem.cpp:106
27+msgid "Pin shortcut"
28+msgstr ""
29+
30+#: plugins/Unity/Launcher/launcheritem.cpp:52
31+msgid "Quit"
32+msgstr "Kat"
33+
34+#: plugins/Unity/Launcher/launcheritem.cpp:106
35+msgid "Unpin shortcut"
36+msgstr ""
37+
38+#: qml/Components/DelayedLockscreen.qml:49
39+msgid "Device Locked"
40+msgstr ""
41+
42+#: qml/Components/DelayedLockscreen.qml:64
43+msgid "You have been locked out due to too many failed passphrase attempts."
44+msgstr ""
45+
46+#: qml/Components/DelayedLockscreen.qml:65
47+msgid "You have been locked out due to too many failed passcode attempts."
48+msgstr ""
49+
50+#: qml/Components/DelayedLockscreen.qml:74
51+#, qt-format
52+msgid "Please wait %1 minute and then try again…"
53+msgid_plural "Please wait %1 minutes and then try again…"
54+msgstr[0] "Maganak %1 minit qambaalaay, kaadu gabbat"
55+msgstr[1] "Maganak %1 minit qambaalaay, kaadu gabbat"
56+
57+#: qml/Components/Dialogs.qml:144
58+msgctxt "Title: Lock/Log out dialog"
59+msgid "Log out"
60+msgstr "Eweq"
61+
62+#: qml/Components/Dialogs.qml:145
63+msgid "Are you sure you want to log out?"
64+msgstr ""
65+
66+#: qml/Components/Dialogs.qml:147
67+msgctxt "Button: Lock the system"
68+msgid "Lock"
69+msgstr "Koflis"
70+
71+#: qml/Components/Dialogs.qml:154
72+msgctxt "Button: Log out from the system"
73+msgid "Log Out"
74+msgstr "Eweq"
75+
76+#: qml/Components/Dialogs.qml:161 qml/Components/Dialogs.qml:194
77+#: qml/Components/Dialogs.qml:253
78+msgid "Cancel"
79+msgstr "Bayis"
80+
81+#: qml/Components/Dialogs.qml:173
82+msgctxt "Title: Reboot/Shut down dialog"
83+msgid "Shut down"
84+msgstr "Bargus"
85+
86+#: qml/Components/Dialogs.qml:174
87+msgid "Are you sure you want to shut down?"
88+msgstr "Bargussuh digga maay litoo?"
89+
90+#: qml/Components/Dialogs.qml:176
91+msgctxt "Button: Reboot the system"
92+msgid "Reboot"
93+msgstr "Wadir-ugus"
94+
95+#: qml/Components/Dialogs.qml:185
96+msgctxt "Button: Shut down the system"
97+msgid "Shut down"
98+msgstr "Bargus"
99+
100+#: qml/Components/Dialogs.qml:207
101+msgctxt "Title: Reboot dialog"
102+msgid "Reboot"
103+msgstr "Wadir-ugus"
104+
105+#: qml/Components/Dialogs.qml:208
106+msgid "Are you sure you want to reboot?"
107+msgstr "Wadir-ugussuh digga maay litoo?"
108+
109+#: qml/Components/Dialogs.qml:210
110+msgid "No"
111+msgstr "Maleey"
112+
113+#: qml/Components/Dialogs.qml:217
114+msgid "Yes"
115+msgstr "Yeey"
116+
117+#: qml/Components/Dialogs.qml:232
118+msgctxt "Title: Power off/Restart dialog"
119+msgid "Power"
120+msgstr "Cayla"
121+
122+#: qml/Components/Dialogs.qml:233
123+msgid ""
124+"Are you sure you would like\n"
125+"to power off?"
126+msgstr "Timmi haytuh digga maay litoo?"
127+
128+#: qml/Components/Dialogs.qml:235
129+msgctxt "Button: Power off the system"
130+msgid "Power off"
131+msgstr "Timmi hayis"
132+
133+#: qml/Components/Dialogs.qml:244
134+msgctxt "Button: Restart the system"
135+msgid "Restart"
136+msgstr "Wadir-qimbis"
137+
138+#: qml/Components/Lockscreen.qml:245
139+msgid "Return to Call"
140+msgstr "Seecol gacis"
141+
142+#: qml/Components/Lockscreen.qml:245
143+msgid "Emergency Call"
144+msgstr ""
145+
146+#: qml/Components/Lockscreen.qml:277
147+msgid "OK"
148+msgstr "Hayya"
149+
150+#: qml/Components/ModeSwitchWarningDialog.qml:32
151+msgid "Apps may have unsaved data:"
152+msgstr ""
153+
154+#: qml/Components/ModeSwitchWarningDialog.qml:57
155+msgid "Re-dock, save your work and close these apps to continue."
156+msgstr ""
157+
158+#: qml/Components/ModeSwitchWarningDialog.qml:63
159+msgid "Or force close now (unsaved data will be lost)."
160+msgstr ""
161+
162+#: qml/Components/ModeSwitchWarningDialog.qml:75
163+msgid "OK, I will reconnect"
164+msgstr ""
165+
166+#: qml/Components/ModeSwitchWarningDialog.qml:76
167+msgid "Reconnect now!"
168+msgstr ""
169+
170+#: qml/Components/ModeSwitchWarningDialog.qml:88
171+msgid "Close all"
172+msgstr "Inkih alif"
173+
174+#: qml/Dash/DashPageHeader.qml:266
175+msgctxt "Button: Open the Ubuntu Store"
176+msgid "Store"
177+msgstr ""
178+
179+#: qml/Dash/DashPageHeader.qml:273
180+msgctxt "Button: Start a search in the current dash scope"
181+msgid "Search"
182+msgstr "Goranto"
183+
184+#: qml/Dash/DashPageHeader.qml:283
185+msgctxt "Button: Show the current dash scope settings"
186+msgid "Settings"
187+msgstr "Massosu"
188+
189+#: qml/Dash/DashPageHeader.qml:290
190+msgid "Remove from Favorites"
191+msgstr ""
192+
193+#: qml/Dash/DashPageHeader.qml:290
194+msgid "Add to Favorites"
195+msgstr ""
196+
197+#: qml/Dash/GenericScopeView.qml:587 qml/Dash/GenericScopeView.qml:745
198+msgid "See less"
199+msgstr ""
200+
201+#: qml/Dash/GenericScopeView.qml:587
202+msgid "See all"
203+msgstr ""
204+
205+#: qml/Dash/GenericScopeView.qml:649
206+msgctxt "Label: Hint for dash search line edit"
207+msgid "Search"
208+msgstr "Goranto"
209+
210+#: qml/Dash/Previews/PreviewActionCombo.qml:35
211+msgid "More..."
212+msgstr ""
213+
214+#: qml/Dash/Previews/PreviewActionCombo.qml:35
215+msgid "Less..."
216+msgstr ""
217+
218+#: qml/Dash/Previews/PreviewCommentInput.qml:68
219+#: qml/Dash/Previews/PreviewRatingInput.qml:174
220+msgid "Send"
221+msgstr "Rub"
222+
223+#: qml/Dash/Previews/PreviewRatingInput.qml:84
224+msgid "Rate this"
225+msgstr ""
226+
227+#: qml/Dash/Previews/PreviewRatingInput.qml:129
228+msgid "Add a review"
229+msgstr ""
230+
231+#: qml/Dash/Previews/PreviewSharing.qml:50
232+msgid "Preview Share Item"
233+msgstr ""
234+
235+#: qml/Dash/PullToRefreshScopeStyle.qml:55
236+msgid "Pull to refresh…"
237+msgstr ""
238+
239+#: qml/Dash/PullToRefreshScopeStyle.qml:60
240+msgid "Release to refresh…"
241+msgstr ""
242+
243+#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
244+msgid "Enable location data"
245+msgstr ""
246+
247+#: qml/Dash/ScopesList.qml:67
248+msgid "Manage"
249+msgstr ""
250+
251+#: qml/Dash/ScopesList.qml:113
252+msgid "Home"
253+msgstr "Dabqi"
254+
255+#: qml/Dash/ScopesList.qml:114
256+msgid "Also installed"
257+msgstr ""
258+
259+#: qml/DisabledScreenNotice.qml:87
260+msgid ""
261+"Your device is now connected to an external display. Use this screen as a "
262+"touch pad to interact with the mouse."
263+msgstr ""
264+
265+#: qml/Greeter/CoverPage.qml:107
266+msgid "Unlock"
267+msgstr ""
268+
269+#: qml/Greeter/LoginList.qml:239
270+msgid "Retry"
271+msgstr "Qagis"
272+
273+#: qml/Greeter/LoginList.qml:240
274+msgid "Tap to unlock"
275+msgstr ""
276+
277+#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:53
278+msgid "Sorry, incorrect passphrase."
279+msgstr ""
280+
281+#: qml/Greeter/NarrowView.qml:55 qml/Wizard/Pages/passwd-confirm.qml:54
282+msgid "Sorry, incorrect passcode."
283+msgstr ""
284+
285+#: qml/Greeter/NarrowView.qml:56
286+msgid "This will be your last attempt."
287+msgstr ""
288+
289+#: qml/Greeter/NarrowView.qml:58
290+msgid ""
291+"If passphrase is entered incorrectly, your phone will conduct a factory "
292+"reset and all personal data will be deleted."
293+msgstr ""
294+
295+#: qml/Greeter/NarrowView.qml:59
296+msgid ""
297+"If passcode is entered incorrectly, your phone will conduct a factory reset "
298+"and all personal data will be deleted."
299+msgstr ""
300+
301+#: qml/Greeter/NarrowView.qml:116
302+#, qt-format
303+msgid "Enter %1"
304+msgstr "%1 culus"
305+
306+#: qml/Greeter/NarrowView.qml:117 qml/Wizard/Pages/passwd-set.qml:60
307+msgid "Enter passphrase"
308+msgstr "Tatur-maxco culus"
309+
310+#: qml/Greeter/NarrowView.qml:118
311+msgid "Enter passcode"
312+msgstr "Tatur-mudenta culus"
313+
314+#: qml/Greeter/NarrowView.qml:119
315+#, qt-format
316+msgid "Sorry, incorrect %1"
317+msgstr ""
318+
319+#: qml/Greeter/NarrowView.qml:120
320+msgid "Sorry, incorrect passphrase"
321+msgstr ""
322+
323+#: qml/Greeter/NarrowView.qml:121
324+msgctxt "passphrase"
325+msgid "Please re-enter"
326+msgstr ""
327+
328+#: qml/Greeter/NarrowView.qml:122
329+msgid "Sorry, incorrect passcode"
330+msgstr ""
331+
332+#: qml/Notifications/NotificationMenuItemFactory.qml:129
333+msgid "Show password"
334+msgstr "Cuumita uybulluy"
335+
336+#: qml/Panel/ActiveCallHint.qml:79
337+msgid "Tap to return to call..."
338+msgstr ""
339+
340+#: qml/Panel/ActiveCallHint.qml:92
341+msgid "Conference"
342+msgstr "Koboxu"
343+
344+#: qml/Panel/Indicators/MenuItemFactory.qml:753
345+msgid "Nothing is playing"
346+msgstr ""
347+
348+#: qml/Panel/Indicators/MenuItemFactory.qml:882
349+#, qt-format
350+msgid "%1 hour"
351+msgid_plural "%1 hours"
352+msgstr[0] "%1 saaqata"
353+msgstr[1] "%1 saaqata"
354+
355+#: qml/Panel/Indicators/MenuItemFactory.qml:886
356+#, qt-format
357+msgid "%1 minute"
358+msgid_plural "%1 minutes"
359+msgstr[0] "%1 miniti"
360+msgstr[1] "%1 miniti"
361+
362+#: qml/Panel/Indicators/MenuItemFactory.qml:891
363+#, qt-format
364+msgid "%1 second"
365+msgid_plural "%1 seconds"
366+msgstr[0] "%1 nammayye"
367+msgstr[1] "%1 nammayye"
368+
369+#: qml/Panel/Indicators/MenuItemFactory.qml:894
370+msgid "0 seconds"
371+msgstr "0 nammayye"
372+
373+#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
374+#: qml/Panel/Indicators/MenuItemFactory.qml:896
375+#, qt-format
376+msgid "%1 remaining"
377+msgstr "%1 raaqe"
378+
379+#: qml/Panel/Indicators/MenuItemFactory.qml:902
380+msgid "In queue…"
381+msgstr ""
382+
383+#: qml/Panel/Indicators/MenuItemFactory.qml:906
384+msgid "Downloading"
385+msgstr "Qulluumah"
386+
387+#: qml/Panel/Indicators/MenuItemFactory.qml:908
388+msgid "Paused, tap to resume"
389+msgstr ""
390+
391+#: qml/Panel/Indicators/MenuItemFactory.qml:910
392+msgid "Canceled"
393+msgstr "Bayteh"
394+
395+#: qml/Panel/Indicators/MenuItemFactory.qml:912
396+msgid "Finished"
397+msgstr "Duudumteh"
398+
399+#: qml/Panel/Indicators/MenuItemFactory.qml:914
400+msgid "Failed, tap to retry"
401+msgstr ""
402+
403+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:155
404+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
405+msgctxt "Button: Send a reply message"
406+msgid "Send"
407+msgstr "Rub"
408+
409+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
410+msgctxt "Label: Hint in message indicator line edit"
411+msgid "Reply"
412+msgstr ""
413+
414+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
415+msgctxt "Button: Call back on phone"
416+msgid "Call back"
417+msgstr ""
418+
419+#: qml/Panel/Indicators/ModemInfoItem.qml:105
420+msgid "Unlock SIM"
421+msgstr ""
422+
423+#: qml/Panel/Indicators/RoamingIndication.qml:27
424+msgid "Roaming"
425+msgstr ""
426+
427+#: qml/Tutorial/TutorialBottom.qml:28
428+msgid "Open special menus"
429+msgstr ""
430+
431+#: qml/Tutorial/TutorialBottom.qml:29
432+msgid "Swipe up from the bottom edge."
433+msgstr ""
434+
435+#: qml/Tutorial/TutorialBottomFinish.qml:24
436+msgid "This action does different things for different apps"
437+msgstr ""
438+
439+#: qml/Tutorial/TutorialBottomFinish.qml:25
440+msgid "Tap here to finish."
441+msgstr ""
442+
443+#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
444+#: qml/Tutorial/TutorialRight.qml:144
445+msgid "Tap here to continue."
446+msgstr ""
447+
448+#: qml/Tutorial/TutorialLeft.qml:26
449+msgid "Open the launcher"
450+msgstr ""
451+
452+#: qml/Tutorial/TutorialLeft.qml:27
453+msgid "Short swipe from the left edge."
454+msgstr ""
455+
456+#: qml/Tutorial/TutorialLeftFinish.qml:24
457+msgid "These are the shortcuts to favorite apps"
458+msgstr ""
459+
460+#: qml/Tutorial/TutorialPage.qml:178
461+msgid "You almost got it!"
462+msgstr ""
463+
464+#: qml/Tutorial/TutorialPage.qml:195
465+msgid "Try again."
466+msgstr ""
467+
468+#: qml/Tutorial/TutorialRight.qml:31
469+msgid "To view open apps"
470+msgstr ""
471+
472+#: qml/Tutorial/TutorialRight.qml:32
473+msgid "Long swipe from the right edge."
474+msgstr ""
475+
476+#: qml/Tutorial/TutorialRight.qml:122
477+msgid "View all your running tasks."
478+msgstr ""
479+
480+#: qml/Wizard/Page.qml:89
481+msgctxt "Button: Go back one page in the Wizard"
482+msgid "Back"
483+msgstr "Derre"
484+
485+#: qml/Wizard/Pages/10-welcome.qml:27
486+msgid "Hi!"
487+msgstr "Nagaale!"
488+
489+#: qml/Wizard/Pages/10-welcome.qml:44
490+msgid "Welcome to your Ubuntu device."
491+msgstr ""
492+
493+#: qml/Wizard/Pages/10-welcome.qml:52
494+msgid "Let’s get started."
495+msgstr "Hayya qimbisnay."
496+
497+#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:133
498+#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
499+#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
500+#: qml/Wizard/Pages/passwd-set.qml:90
501+msgid "Continue"
502+msgstr "Tatur"
503+
504+#: qml/Wizard/Pages/20-sim.qml:25
505+msgid "Add a SIM card and restart your device"
506+msgstr ""
507+
508+#: qml/Wizard/Pages/20-sim.qml:59
509+msgid "Without it, you won’t be able to make calls or use text messaging."
510+msgstr ""
511+
512+#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
513+msgid "Skip"
514+msgstr "Kaqit"
515+
516+#: qml/Wizard/Pages/30-passwd-type.qml:39
517+msgid "Lock security"
518+msgstr ""
519+
520+#: qml/Wizard/Pages/30-passwd-type.qml:79
521+msgid "Please select how you’d like to unlock your device."
522+msgstr ""
523+
524+#: qml/Wizard/Pages/30-passwd-type.qml:102
525+msgctxt "Label: Type of security method"
526+msgid "Swipe"
527+msgstr "Uysuttuc"
528+
529+#: qml/Wizard/Pages/30-passwd-type.qml:103
530+msgctxt "Label: Description of security method"
531+msgid "No security"
532+msgstr ""
533+
534+#: qml/Wizard/Pages/30-passwd-type.qml:105
535+msgctxt "Label: Type of security method"
536+msgid "Passcode"
537+msgstr ""
538+
539+#: qml/Wizard/Pages/30-passwd-type.qml:106
540+msgctxt "Label: Description of security method"
541+msgid "4 digits only"
542+msgstr ""
543+
544+#: qml/Wizard/Pages/30-passwd-type.qml:108
545+msgctxt "Label: Type of security method"
546+msgid "Passphrase"
547+msgstr ""
548+
549+#: qml/Wizard/Pages/30-passwd-type.qml:109
550+msgctxt "Label: Description of security method"
551+msgid "Numbers and letters"
552+msgstr ""
553+
554+#: qml/Wizard/Pages/40-wifi.qml:29
555+msgid "Connect to Wi‑Fi"
556+msgstr ""
557+
558+#: qml/Wizard/Pages/40-wifi.qml:168
559+msgid "Available networks…"
560+msgstr ""
561+
562+#: qml/Wizard/Pages/40-wifi.qml:169
563+msgid "No available networks."
564+msgstr ""
565+
566+#: qml/Wizard/Pages/50-location.qml:27
567+msgid "Location"
568+msgstr ""
569+
570+#: qml/Wizard/Pages/50-location.qml:62
571+msgid "Let the phone detect your location:"
572+msgstr ""
573+
574+#: qml/Wizard/Pages/50-location.qml:69
575+msgid "Using GPS only (less accurate)"
576+msgstr ""
577+
578+#: qml/Wizard/Pages/50-location.qml:86
579+msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
580+msgstr ""
581+
582+#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
583+#: qml/Wizard/Pages/50-location.qml:103
584+msgid ""
585+"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
586+"conditions</a>."
587+msgstr ""
588+
589+#: qml/Wizard/Pages/50-location.qml:112
590+msgid "Not at all"
591+msgstr ""
592+
593+#: qml/Wizard/Pages/50-location.qml:124
594+msgid "You can change your mind later in <b>System Settings</b>."
595+msgstr ""
596+
597+#: qml/Wizard/Pages/60-reporting.qml:26
598+msgid "Improving your experience"
599+msgstr ""
600+
601+#: qml/Wizard/Pages/60-reporting.qml:46
602+msgid ""
603+"Your phone is set up to automatically report errors to Canonical and its "
604+"partners, the makers of the operating system."
605+msgstr ""
606+
607+#: qml/Wizard/Pages/60-reporting.qml:53
608+msgid ""
609+"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
610+"Privacy</b>"
611+msgstr ""
612+
613+#: qml/Wizard/Pages/80-finished.qml:24
614+msgid "All done"
615+msgstr ""
616+
617+#: qml/Wizard/Pages/80-finished.qml:39
618+msgid "Nice work!"
619+msgstr ""
620+
621+#: qml/Wizard/Pages/80-finished.qml:46
622+msgid "Your device is now ready to use."
623+msgstr ""
624+
625+#: qml/Wizard/Pages/80-finished.qml:53
626+msgid "Finish"
627+msgstr ""
628+
629+#: qml/Wizard/Pages/here-terms.qml:27
630+msgid "Terms & Conditions"
631+msgstr ""
632+
633+#: qml/Wizard/Pages/passwd-confirm.qml:49
634+msgid "Confirm passphrase"
635+msgstr ""
636+
637+#: qml/Wizard/Pages/passwd-confirm.qml:50
638+msgid "Confirm passcode"
639+msgstr ""
640+
641+#: qml/Wizard/Pages/passwd-confirm.qml:53
642+#: qml/Wizard/Pages/passwd-confirm.qml:54
643+msgid "Please try again."
644+msgstr ""
645+
646+#: qml/Wizard/Pages/passwd-set.qml:61
647+msgid "Choose your passcode"
648+msgstr ""
649+
650+#: qml/Wizard/Pages/passwd-set.qml:68
651+msgid "Passphrase must be 4 characters long"
652+msgstr ""
653+
654+#. Translators: This is the arrow for "Back" buttons
655+#: qml/Wizard/StackButton.qml:39
656+#, qt-format
657+msgid "〈 %1"
658+msgstr ""
659+
660+#. Translators: This is the arrow for "Forward" buttons
661+#: qml/Wizard/StackButton.qml:42
662+#, qt-format
663+msgid "%1 〉"
664+msgstr ""
665+
666+#~ msgid "Welcome to your Ubuntu phone."
667+#~ msgstr "Ubuntu Telefoonul arcib"
po/am.po+21−4
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-11-19 19:27+0000\n"
1212"Last-Translator: samson <Unknown>\n"
1313"Language-Team: Amharic <am@li.org>\n"
14+"Language: am\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -670,6 +671,21 @@ msgstr "〈 %1"
670671msgid "%1 〉"
671672msgstr "%1 〉"
672673
674+#~ msgid ""
675+#~ "Your device is now connected to an external display. Use this screen as a "
676+#~ "touch pad to interact with the mouse."
677+#~ msgstr ""
678+#~ "የ እርስዎ አካል አሁን ከ ውጪ ማሳያ ጋር ተገናኝቷል: ይህን መመልከቻ እንደ ተችፓድ ከ አይጥ ጋር ተባብሮ ይሰራል"
679+
680+#~ msgid "Welcome to your Ubuntu device."
681+#~ msgstr "እንኳን ድህና መጡ ወደ ኡቡንቱ"
682+
683+#~ msgid "Please select how you’d like to unlock your device."
684+#~ msgstr "እባክዎን የ እርስዎን አካል እንዴት እንደሚከፈት ይምረጡ"
685+
686+#~ msgid "Your device is now ready to use."
687+#~ msgstr "የ እርስዎ አካል አሁን ዝግጁ ነው"
688+
673689#~ msgid "Top edge"
674690#~ msgstr "የላይ ጠርዝ"
675691
@@ -752,7 +768,8 @@ msgstr "%1 〉"
752768#~ "You have now mastered the edge gestures and can start using the "
753769#~ "phone<br><br>Tap on the screen to start"
754770#~ msgstr ""
755−#~ "አሁን የ ጠርዝ እንቅስቃሴን አውቀዋል እና መጀመር ይችላሉ ስልኩን መጠቀም <br><br>መመልከቻውን መታ ያድርጉ ለመጀመር"
771+#~ "አሁን የ ጠርዝ እንቅስቃሴን አውቀዋል እና መጀመር ይችላሉ ስልኩን መጠቀም <br><br>መመልከቻውን መታ ያድርጉ "
772+#~ "ለመጀመር"
756773
757774#~ msgid "Restart"
758775#~ msgstr "እንደገና ማስጀመሪያ"
po/ar.po+7−7
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-29 09:41+0000\n"
1212"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
1313"Language-Team: Arabic <ar@li.org>\n"
14+"Language: ar\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
1819"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -530,8 +531,7 @@ msgstr "أدخِل شريحة SIM ثم أعِد تشغيل الجهاز"
530531
531532#: qml/Wizard/Pages/20-sim.qml:59
532533msgid "Without it, you won’t be able to make calls or use text messaging."
533−msgstr ""
534−"بدونها لن تتمكن من إجراء أي مكالمات هاتفية أو استخدام الرسائل النصية."
534+msgstr "بدونها لن تتمكن من إجراء أي مكالمات هاتفية أو استخدام الرسائل النصية."
535535
536536#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
537537msgid "Skip"
@@ -748,8 +748,8 @@ msgstr ""
748748#~ "You have now mastered the edge gestures and can start using the "
749749#~ "phone<br><br>Tap on the screen to start"
750750#~ msgstr ""
751−#~ "أنت الآن بارع في إيماءات الحواف ويمكنك البدء باستخدام هاتفك<br><br>انقر على "
752−#~ "الشاشة للبدء"
751+#~ "أنت الآن بارع في إيماءات الحواف ويمكنك البدء باستخدام هاتفك<br><br>انقر "
752+#~ "على الشاشة للبدء"
753753
754754#~ msgid "%a %l:%M %p"
755755#~ msgstr "%a %l:%M %p"
po/ast.po+19−18
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-10-06 12:07+0000\n"
11+"PO-Revision-Date: 2016-02-19 19:39+0000\n"
1212"Last-Translator: Xuacu Saturio <xuacusk8@gmail.com>\n"
1313"Language-Team: Asturian <ast@li.org>\n"
14+"Language: ast\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -45,8 +46,7 @@ msgstr "Quedasti bloquiáu polos escesivos intentos fallíos de fras de pasu."
4546
4647#: qml/Components/DelayedLockscreen.qml:65
4748msgid "You have been locked out due to too many failed passcode attempts."
48−msgstr ""
49−"Quedasti bloquiáu polos escesivos intentos fallíos de códigu de pasu."
49+msgstr "Quedasti bloquiáu polos escesivos intentos fallíos de códigu de pasu."
5050
5151#: qml/Components/DelayedLockscreen.qml:74
5252#, qt-format
@@ -152,27 +152,29 @@ msgstr "Aceutar"
152152
153153#: qml/Components/ModeSwitchWarningDialog.qml:32
154154msgid "Apps may have unsaved data:"
155−msgstr ""
155+msgstr "Apps que pueden tener datos sin guardar:"
156156
157157#: qml/Components/ModeSwitchWarningDialog.qml:57
158158msgid "Re-dock, save your work and close these apps to continue."
159159msgstr ""
160+"Pa siguir coneuta nuevamente'l preséu, guarda'l trabayu y zarra estes "
161+"aplicaciones."
160162
161163#: qml/Components/ModeSwitchWarningDialog.qml:63
162164msgid "Or force close now (unsaved data will be lost)."
163−msgstr ""
165+msgstr "O fuerza salir agora (perderás tolos datos sin guardar)."
164166
165167#: qml/Components/ModeSwitchWarningDialog.qml:75
166168msgid "OK, I will reconnect"
167−msgstr ""
169+msgstr "D'alcuerdu, reconeutaré"
168170
169171#: qml/Components/ModeSwitchWarningDialog.qml:76
170172msgid "Reconnect now!"
171−msgstr ""
173+msgstr "Reconeutar agora."
172174
173175#: qml/Components/ModeSwitchWarningDialog.qml:88
174176msgid "Close all"
175−msgstr ""
177+msgstr "Zarrar too"
176178
177179#: qml/Dash/DashPageHeader.qml:265
178180msgctxt "Button: Open the Ubuntu Store"
@@ -233,7 +235,7 @@ msgstr "Amestar una reseña"
233235
234236#: qml/Dash/Previews/PreviewSharing.qml:51
235237msgid "Preview Share Item"
236−msgstr ""
238+msgstr "Entever l'elementu compartíu"
237239
238240#: qml/Dash/PullToRefreshScopeStyle.qml:55
239241msgid "Pull to refresh…"
@@ -409,7 +411,7 @@ msgstr "Falló, toca pa reintentar"
409411#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
410412msgctxt "Button: Send a reply message"
411413msgid "Send"
412−msgstr ""
414+msgstr "Unviar"
413415
414416#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
415417msgctxt "Label: Hint in message indicator line edit"
@@ -419,7 +421,7 @@ msgstr "Responder"
419421#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
420422msgctxt "Button: Call back on phone"
421423msgid "Call back"
422−msgstr ""
424+msgstr "Devolver llamada"
423425
424426#: qml/Panel/Indicators/ModemInfoItem.qml:105
425427msgid "Unlock SIM"
@@ -582,8 +584,7 @@ msgstr "Namái usando GPS (menos precisión)"
582584
583585#: qml/Wizard/Pages/50-location.qml:86
584586msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
585−msgstr ""
586−"Usando GPS, Wi-fi anónimes ya información de redes móviles (aconseyao)"
587+msgstr "Usando GPS, Wi-fi anónimes ya información de redes móviles (aconseyao)"
587588
588589#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
589590#: qml/Wizard/Pages/50-location.qml:103
@@ -701,8 +702,8 @@ msgstr "%1 〉"
701702
702703#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
703704#~ msgstr ""
704−#~ "Esliza'l deu dende la esquierda p'amosar el llanzador y acceder rápidamente "
705−#~ "a les aplicaciones"
705+#~ "Esliza'l deu dende la esquierda p'amosar el llanzador y acceder "
706+#~ "rápidamente a les aplicaciones"
706707
707708#~ msgid "Well done"
708709#~ msgstr "Bien fecho"
po/az.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-09-03 16:39+0000\n"
1212"Last-Translator: Nicat Məmmədov <n1c4t97@gmail.com>\n"
1313"Language-Team: Azerbaijani <az@li.org>\n"
14+"Language: az\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/be.po+10−10
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-12-13 13:12+0000\n"
1212"Last-Translator: Mikhail_SaTuRn <mikhail_saturn@tut.by>\n"
1313"Language-Team: Belarusian <be@li.org>\n"
14+"Language: be\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
19−"X-Launchpad-Export-Date: 2015-12-14 05:32+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
18+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -42,8 +43,7 @@ msgstr "Прылада заблакаваная"
4243
4344#: qml/Components/DelayedLockscreen.qml:64
4445msgid "You have been locked out due to too many failed passphrase attempts."
45−msgstr ""
46−"Вы былі заблакаваныя з-за занадта вялікай колькасці няўдалых спробаў."
46+msgstr "Вы былі заблакаваныя з-за занадта вялікай колькасці няўдалых спробаў."
4747
4848#: qml/Components/DelayedLockscreen.qml:65
4949msgid "You have been locked out due to too many failed passcode attempts."
@@ -237,7 +237,7 @@ msgstr "Дадаць рэцэнзію"
237237
238238#: qml/Dash/Previews/PreviewSharing.qml:51
239239msgid "Preview Share Item"
240−msgstr "Падзяліцца праглядаймым"
240+msgstr "Праглядзець элемент"
241241
242242#: qml/Dash/PullToRefreshScopeStyle.qml:55
243243msgid "Pull to refresh…"
@@ -735,8 +735,8 @@ msgstr "%1 〉"
735735
736736#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
737737#~ msgstr ""
738−#~ "Правядзіце пальцам ад левага краю, каб адкрыць панэль запуску для паскарэння "
739−#~ "доступу да праграм"
738+#~ "Правядзіце пальцам ад левага краю, каб адкрыць панэль запуску для "
739+#~ "паскарэння доступу да праграм"
740740
741741#~ msgid "Skip intro"
742742#~ msgstr "Прапусціць уводзіны"
po/bg.po+6−5
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-04-12 14:43+0000\n"
1212"Last-Translator: George Karavasilev <kokoto-java@ubuntu.com>\n"
1313"Language-Team: Bulgarian <bg@li.org>\n"
14+"Language: bg\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -710,8 +711,8 @@ msgstr ""
710711
711712#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
712713#~ msgstr ""
713−#~ "Приплъзнете пръста си от левия край към десния, за да отворите стартера за "
714−#~ "бърз достъп до приложенията"
714+#~ "Приплъзнете пръста си от левия край към десния, за да отворите стартера "
715+#~ "за бърз достъп до приложенията"
715716
716717#~ msgid "Try swiping from the right edge to unlock the phone"
717718#~ msgstr ""
po/bn.po+163−100
@@ -6,26 +6,27 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-11-27 19:38+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Bengali <bn@li.org>\n"
14+"Language: bn\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
23−msgstr ""
24+msgstr "পাসওয়ার্ড: "
2425
2526#: plugins/Unity/Launcher/launcheritem.cpp:47
2627#: plugins/Unity/Launcher/launcheritem.cpp:106
2728msgid "Pin shortcut"
28−msgstr ""
29+msgstr "পিন"
2930
3031#: plugins/Unity/Launcher/launcheritem.cpp:52
3132msgid "Quit"
@@ -33,26 +34,26 @@ msgstr ""
3334
3435#: plugins/Unity/Launcher/launcheritem.cpp:106
3536msgid "Unpin shortcut"
36−msgstr ""
37+msgstr "আনপিন"
3738
3839#: qml/Components/DelayedLockscreen.qml:49
3940msgid "Device Locked"
40−msgstr ""
41+msgstr "ডিভাইসটি লক করা"
4142
4243#: qml/Components/DelayedLockscreen.qml:64
4344msgid "You have been locked out due to too many failed passphrase attempts."
44−msgstr ""
45+msgstr "অধিকবার পাসফ্রেজ ভুল দেওয়ার কারনে আপনার আইডি লক করা হয়েছে"
4546
4647#: qml/Components/DelayedLockscreen.qml:65
4748msgid "You have been locked out due to too many failed passcode attempts."
48−msgstr ""
49+msgstr "অধিকবার পাসকোড ভুল করার কারনে আপনার আইডি লক করা হয়েছে"
4950
5051#: qml/Components/DelayedLockscreen.qml:74
5152#, qt-format
5253msgid "Please wait %1 minute and then try again…"
5354msgid_plural "Please wait %1 minutes and then try again…"
54−msgstr[0] ""
55−msgstr[1] ""
55+msgstr[0] "অনুগ্রহ করে %1 মিনিট অপেক্ষা করুন এবং পরবর্তীতে চেষ্টা করুন..."
56+msgstr[1] "অনুগ্রহ করে %1 মিনিট অপেক্ষা করুন এবং পরবর্তীতে চেষ্টা করুন..."
5657
5758#: qml/Components/Dialogs.qml:144
5859msgctxt "Title: Lock/Log out dialog"
@@ -61,12 +62,12 @@ msgstr ""
6162
6263#: qml/Components/Dialogs.qml:145
6364msgid "Are you sure you want to log out?"
64−msgstr ""
65+msgstr "আপনি কি লগ আউট করতে চান?"
6566
6667#: qml/Components/Dialogs.qml:147
6768msgctxt "Button: Lock the system"
6869msgid "Lock"
69−msgstr ""
70+msgstr "লক করুন"
7071
7172#: qml/Components/Dialogs.qml:154
7273msgctxt "Button: Log out from the system"
@@ -76,43 +77,43 @@ msgstr ""
7677#: qml/Components/Dialogs.qml:161 qml/Components/Dialogs.qml:194
7778#: qml/Components/Dialogs.qml:253
7879msgid "Cancel"
79−msgstr ""
80+msgstr "বাতিল"
8081
8182#: qml/Components/Dialogs.qml:173
8283msgctxt "Title: Reboot/Shut down dialog"
8384msgid "Shut down"
84−msgstr ""
85+msgstr "বন্ধ করুন"
8586
8687#: qml/Components/Dialogs.qml:174
8788msgid "Are you sure you want to shut down?"
88−msgstr ""
89+msgstr "আপনি কি কম্পিউটার বন্ধ করতে চান?"
8990
9091#: qml/Components/Dialogs.qml:176
9192msgctxt "Button: Reboot the system"
9293msgid "Reboot"
93−msgstr ""
94+msgstr "পুনরায় চালু করুন"
9495
9596#: qml/Components/Dialogs.qml:185
9697msgctxt "Button: Shut down the system"
9798msgid "Shut down"
98−msgstr ""
99+msgstr "বন্ধ করুন"
99100
100101#: qml/Components/Dialogs.qml:207
101102msgctxt "Title: Reboot dialog"
102103msgid "Reboot"
103−msgstr ""
104+msgstr "পুনরায় চালু"
104105
105106#: qml/Components/Dialogs.qml:208
106107msgid "Are you sure you want to reboot?"
107−msgstr ""
108+msgstr "আপনি কি পুনরায় চালু করতে চান?"
108109
109110#: qml/Components/Dialogs.qml:210
110111msgid "No"
111−msgstr ""
112+msgstr "না"
112113
113114#: qml/Components/Dialogs.qml:217
114115msgid "Yes"
115−msgstr ""
116+msgstr "হ্যাঁ"
116117
117118#: qml/Components/Dialogs.qml:232
118119msgctxt "Title: Power off/Restart dialog"
@@ -124,28 +125,30 @@ msgid ""
124125"Are you sure you would like\n"
125126"to power off?"
126127msgstr ""
128+"আপনি নিশ্চিত যে আপনি\n"
129+"বন্ধ করতে চান?"
127130
128131#: qml/Components/Dialogs.qml:235
129132msgctxt "Button: Power off the system"
130133msgid "Power off"
131−msgstr ""
134+msgstr "বন্ধ করুন"
132135
133136#: qml/Components/Dialogs.qml:244
134137msgctxt "Button: Restart the system"
135138msgid "Restart"
136−msgstr ""
139+msgstr "পুনরায় চালু"
137140
138141#: qml/Components/Lockscreen.qml:245
139142msgid "Return to Call"
140−msgstr ""
143+msgstr "কল এ ফিরে যান"
141144
142145#: qml/Components/Lockscreen.qml:245
143146msgid "Emergency Call"
144−msgstr ""
147+msgstr "জরুরী কল"
145148
146149#: qml/Components/Lockscreen.qml:277
147150msgid "OK"
148−msgstr ""
151+msgstr "ঠিক আছে"
149152
150153#: qml/Components/ModeSwitchWarningDialog.qml:32
151154msgid "Apps may have unsaved data:"
@@ -174,59 +177,59 @@ msgstr ""
174177#: qml/Dash/DashPageHeader.qml:265
175178msgctxt "Button: Open the Ubuntu Store"
176179msgid "Store"
177−msgstr ""
180+msgstr "স্টোর"
178181
179182#: qml/Dash/DashPageHeader.qml:272
180183msgctxt "Button: Start a search in the current dash scope"
181184msgid "Search"
182−msgstr ""
185+msgstr "খুঁজুন"
183186
184187#: qml/Dash/DashPageHeader.qml:282
185188msgctxt "Button: Show the current dash scope settings"
186189msgid "Settings"
187−msgstr ""
190+msgstr "সেটিংস"
188191
189192#: qml/Dash/DashPageHeader.qml:289
190193msgid "Remove from Favorites"
191−msgstr ""
194+msgstr "পছন্দ থেকে মুছে ফেলুন"
192195
193196#: qml/Dash/DashPageHeader.qml:289
194197msgid "Add to Favorites"
195−msgstr ""
198+msgstr "পছন্দতে যোগ করুন"
196199
197200#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
198201msgid "See less"
199−msgstr ""
202+msgstr "কম দেখুন"
200203
201204#: qml/Dash/GenericScopeView.qml:576
202205msgid "See all"
203−msgstr ""
206+msgstr "সব দেখুন"
204207
205208#: qml/Dash/GenericScopeView.qml:638
206209msgctxt "Label: Hint for dash search line edit"
207210msgid "Search"
208−msgstr ""
211+msgstr "খুঁজুন"
209212
210213#: qml/Dash/Previews/PreviewActionCombo.qml:35
211214msgid "More..."
212−msgstr ""
215+msgstr "আরো..."
213216
214217#: qml/Dash/Previews/PreviewActionCombo.qml:35
215218msgid "Less..."
216−msgstr ""
219+msgstr "কম..."
217220
218221#: qml/Dash/Previews/PreviewCommentInput.qml:68
219222#: qml/Dash/Previews/PreviewRatingInput.qml:174
220223msgid "Send"
221−msgstr ""
224+msgstr "পাঠান"
222225
223226#: qml/Dash/Previews/PreviewRatingInput.qml:84
224227msgid "Rate this"
225−msgstr ""
228+msgstr "রেটিং দিন"
226229
227230#: qml/Dash/Previews/PreviewRatingInput.qml:129
228231msgid "Add a review"
229−msgstr ""
232+msgstr "আপনার মতামত দিন"
230233
231234#: qml/Dash/Previews/PreviewSharing.qml:51
232235msgid "Preview Share Item"
@@ -234,19 +237,19 @@ msgstr ""
234237
235238#: qml/Dash/PullToRefreshScopeStyle.qml:55
236239msgid "Pull to refresh…"
237−msgstr ""
240+msgstr "রিফ্রেশ করার জন্য টানুন"
238241
239242#: qml/Dash/PullToRefreshScopeStyle.qml:60
240243msgid "Release to refresh…"
241−msgstr ""
244+msgstr "রিফ্রেশ করার জন্য ছেড়ে দিন"
242245
243246#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
244247msgid "Enable location data"
245−msgstr ""
248+msgstr "অবস্থান নির্ণয় চালু করুন"
246249
247250#: qml/Dash/ScopesList.qml:67
248251msgid "Manage"
249−msgstr ""
252+msgstr "ব্যবস্থাপনা"
250253
251254#: qml/Dash/ScopesList.qml:113
252255msgid "Home"
@@ -254,7 +257,7 @@ msgstr ""
254257
255258#: qml/Dash/ScopesList.qml:114
256259msgid "Also installed"
257−msgstr ""
260+msgstr "আরও ইন্সটল করা রয়েছে..."
258261
259262#: qml/DisabledScreenNotice.qml:42
260263msgid "Your device is now connected to an external display."
@@ -262,7 +265,7 @@ msgstr ""
262265
263266#: qml/Greeter/CoverPage.qml:107
264267msgid "Unlock"
265−msgstr ""
268+msgstr "লক খুলুন"
266269
267270#: qml/Greeter/LoginList.qml:236
268271msgid "Retry"
@@ -270,133 +273,133 @@ msgstr ""
270273
271274#: qml/Greeter/LoginList.qml:237
272275msgid "Tap to unlock"
273−msgstr ""
276+msgstr "লক খোলার জন্য চাপ দিন"
274277
275278#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:53
276279msgid "Sorry, incorrect passphrase."
277−msgstr ""
280+msgstr "দুঃখিত, পাসওয়ার্ডটি ভুল হয়েছে।"
278281
279282#: qml/Greeter/NarrowView.qml:55 qml/Wizard/Pages/passwd-confirm.qml:54
280283msgid "Sorry, incorrect passcode."
281−msgstr ""
284+msgstr "দুঃখিত, পাসকোডটি ভুল হয়েছে।"
282285
283286#: qml/Greeter/NarrowView.qml:56
284287msgid "This will be your last attempt."
285−msgstr ""
288+msgstr "এটিই আপনার সর্বশেষ সুযোগ।"
286289
287290#: qml/Greeter/NarrowView.qml:58
288291msgid ""
289292"If passphrase is entered incorrectly, your phone will conduct a factory "
290293"reset and all personal data will be deleted."
291−msgstr ""
294+msgstr "ভুল পাসওয়ার্ড প্রদান করলে, আপনার ফোনটিতে থাকা সকল ব্যক্তিগত তথ্য মুছে যাবে।"
292295
293296#: qml/Greeter/NarrowView.qml:59
294297msgid ""
295298"If passcode is entered incorrectly, your phone will conduct a factory reset "
296299"and all personal data will be deleted."
297−msgstr ""
300+msgstr "ভুল পাসকোড প্রদান করলে, আপনার ফোনটির সকল ব্যক্তিগত তথ্য মুছে যাবে।"
298301
299302#: qml/Greeter/NarrowView.qml:116
300303#, qt-format
301304msgid "Enter %1"
302−msgstr ""
305+msgstr "%1 লিখুন"
303306
304307#: qml/Greeter/NarrowView.qml:117 qml/Wizard/Pages/passwd-set.qml:60
305308msgid "Enter passphrase"
306−msgstr ""
309+msgstr "পাসওয়ার্ড লিখুন"
307310
308311#: qml/Greeter/NarrowView.qml:118
309312msgid "Enter passcode"
310−msgstr ""
313+msgstr "পাসকোড লিখুন"
311314
312315#: qml/Greeter/NarrowView.qml:119
313316#, qt-format
314317msgid "Sorry, incorrect %1"
315−msgstr ""
318+msgstr "দুঃখিত, %1 ভুল হয়েছে"
316319
317320#: qml/Greeter/NarrowView.qml:120
318321msgid "Sorry, incorrect passphrase"
319−msgstr ""
322+msgstr "দুঃখিত, পাসওয়ার্ড ভুল হয়েছে"
320323
321324#: qml/Greeter/NarrowView.qml:121
322325msgctxt "passphrase"
323326msgid "Please re-enter"
324−msgstr ""
327+msgstr "অনুগ্রহ করে আবার লিখুন"
325328
326329#: qml/Greeter/NarrowView.qml:122
327330msgid "Sorry, incorrect passcode"
328−msgstr ""
331+msgstr "দুঃখিত, পাসকোড ভুল হয়েছে"
329332
330333#: qml/Notifications/NotificationMenuItemFactory.qml:129
331334msgid "Show password"
332−msgstr ""
335+msgstr "পাসওয়ার্ড দেখান"
333336
334337#: qml/Panel/ActiveCallHint.qml:79
335338msgid "Tap to return to call..."
336−msgstr ""
339+msgstr "কলে ফিরে যেতে চাপ দিন..."
337340
338341#: qml/Panel/ActiveCallHint.qml:92
339342msgid "Conference"
340−msgstr ""
343+msgstr "কনফারেন্স"
341344
342345#: qml/Panel/Indicators/MenuItemFactory.qml:731
343346msgid "Nothing is playing"
344−msgstr ""
347+msgstr "কোন কিছু বাজছে না।"
345348
346349#: qml/Panel/Indicators/MenuItemFactory.qml:860
347350#, qt-format
348351msgid "%1 hour"
349352msgid_plural "%1 hours"
350−msgstr[0] ""
351−msgstr[1] ""
353+msgstr[0] "%1 ঘণ্টা"
354+msgstr[1] "%1 ঘণ্টা"
352355
353356#: qml/Panel/Indicators/MenuItemFactory.qml:864
354357#, qt-format
355358msgid "%1 minute"
356359msgid_plural "%1 minutes"
357−msgstr[0] ""
358−msgstr[1] ""
360+msgstr[0] "%1 মিনিট"
361+msgstr[1] "%1 মিনিট"
359362
360363#: qml/Panel/Indicators/MenuItemFactory.qml:869
361364#, qt-format
362365msgid "%1 second"
363366msgid_plural "%1 seconds"
364−msgstr[0] ""
365−msgstr[1] ""
367+msgstr[0] "%1 সেকেন্ড"
368+msgstr[1] "%1 সেকেন্ড"
366369
367370#: qml/Panel/Indicators/MenuItemFactory.qml:872
368371msgid "0 seconds"
369−msgstr ""
372+msgstr "0 সেকেন্ড"
370373
371374#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
372375#: qml/Panel/Indicators/MenuItemFactory.qml:874
373376#, qt-format
374377msgid "%1 remaining"
375−msgstr ""
378+msgstr "%1 বাকি"
376379
377380#: qml/Panel/Indicators/MenuItemFactory.qml:880
378381msgid "In queue…"
379−msgstr ""
382+msgstr "অপেক্ষায় রয়েছে..."
380383
381384#: qml/Panel/Indicators/MenuItemFactory.qml:884
382385msgid "Downloading"
383−msgstr ""
386+msgstr "ডাউনলোড হচ্ছে"
384387
385388#: qml/Panel/Indicators/MenuItemFactory.qml:886
386389msgid "Paused, tap to resume"
387−msgstr ""
390+msgstr "থামানো, শুরু করতে চাপ দিন"
388391
389392#: qml/Panel/Indicators/MenuItemFactory.qml:888
390393msgid "Canceled"
391−msgstr ""
394+msgstr "বাতিল হয়েছে"
392395
393396#: qml/Panel/Indicators/MenuItemFactory.qml:890
394397msgid "Finished"
395−msgstr ""
398+msgstr "শেষ"
396399
397400#: qml/Panel/Indicators/MenuItemFactory.qml:892
398401msgid "Failed, tap to retry"
399−msgstr ""
402+msgstr "ব্যার্থ হয়েছে, পুনরায় চেষ্টা করতে চাপ দিন"
400403
401404#: qml/Panel/Indicators/MessageMenuItemFactory.qml:155
402405#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
@@ -407,20 +410,20 @@ msgstr ""
407410#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
408411msgctxt "Label: Hint in message indicator line edit"
409412msgid "Reply"
410−msgstr ""
413+msgstr "উত্তর দিন"
411414
412415#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
413416msgctxt "Button: Call back on phone"
414417msgid "Call back"
415−msgstr ""
418+msgstr "কল ব্যাক"
416419
417420#: qml/Panel/Indicators/ModemInfoItem.qml:105
418421msgid "Unlock SIM"
419−msgstr ""
422+msgstr "সিম লক খুলুন করুন"
420423
421424#: qml/Panel/Indicators/RoamingIndication.qml:27
422425msgid "Roaming"
423−msgstr ""
426+msgstr "রোমিং"
424427
425428#: qml/Tutorial/TutorialBottom.qml:28
426429msgid "Open special menus"
@@ -428,11 +431,11 @@ msgstr ""
428431
429432#: qml/Tutorial/TutorialBottom.qml:29
430433msgid "Swipe up from the bottom edge."
431−msgstr ""
434+msgstr "নিচের প্রান্ত হতে উপরের দিকে সোয়াইপ করুন।"
432435
433436#: qml/Tutorial/TutorialBottomFinish.qml:24
434437msgid "This action does different things for different apps"
435−msgstr ""
438+msgstr "এই কাজটি বিভিন্ন অ্যাপের জন্য ভিন্ন ভিন্ন ভাবে কাজ করে।"
436439
437440#: qml/Tutorial/TutorialBottomFinish.qml:25
438441msgid "Tap here to finish."
@@ -441,11 +444,11 @@ msgstr ""
441444#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
442445#: qml/Tutorial/TutorialRight.qml:144
443446msgid "Tap here to continue."
444−msgstr ""
447+msgstr "অগ্রসর হওয়ার জন্য এখানে চাপ দিন।"
445448
446449#: qml/Tutorial/TutorialLeft.qml:26
447450msgid "Open the launcher"
448−msgstr ""
451+msgstr "লঞ্চার খুলুন"
449452
450453#: qml/Tutorial/TutorialLeft.qml:27
451454msgid "Short swipe from the left edge."
@@ -453,19 +456,19 @@ msgstr ""
453456
454457#: qml/Tutorial/TutorialLeftFinish.qml:24
455458msgid "These are the shortcuts to favorite apps"
456−msgstr ""
459+msgstr "এগুলো আপনার প্রিয় অ্যাপেরর শর্টকাট"
457460
458461#: qml/Tutorial/TutorialPage.qml:178
459462msgid "You almost got it!"
460−msgstr ""
463+msgstr "আপনি প্রায় পেরে গেছেন!"
461464
462465#: qml/Tutorial/TutorialPage.qml:195
463466msgid "Try again."
464−msgstr ""
467+msgstr "আবার চেষ্টা করুন"
465468
466469#: qml/Tutorial/TutorialRight.qml:31
467470msgid "To view open apps"
468−msgstr ""
471+msgstr "সচল অ্যাপগুলো দেখার জন্য"
469472
470473#: qml/Tutorial/TutorialRight.qml:32
471474msgid "Long swipe from the right edge."
@@ -486,38 +489,38 @@ msgstr ""
486489
487490#: qml/Wizard/Pages/10-welcome.qml:44
488491msgid "Welcome to your Ubuntu phone."
489−msgstr ""
492+msgstr "আপনার উবুন্টু ফোনে স্বাগতম।"
490493
491494#: qml/Wizard/Pages/10-welcome.qml:52
492495msgid "Let’s get started."
493−msgstr ""
496+msgstr "আসুন শুরু করা যাক।"
494497
495498#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
496499#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
497500#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
498501#: qml/Wizard/Pages/passwd-set.qml:90
499502msgid "Continue"
500−msgstr ""
503+msgstr "পরবর্তী"
501504
502505#: qml/Wizard/Pages/20-sim.qml:25
503506msgid "Add a SIM card and restart your device"
504−msgstr ""
507+msgstr "সিম কার্ড যোগ করুন এবং ফোন পুনরায় চালু করুন।"
505508
506509#: qml/Wizard/Pages/20-sim.qml:59
507510msgid "Without it, you won’t be able to make calls or use text messaging."
508−msgstr ""
511+msgstr "এটি ছাড়া, আপনি ফোন কল বা টেক্সট মেসেজ ব্যবহার করতে পারবেন না।"
509512
510513#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
511514msgid "Skip"
512−msgstr ""
515+msgstr "এড়িয়ে যান"
513516
514517#: qml/Wizard/Pages/30-passwd-type.qml:39
515518msgid "Lock security"
516−msgstr ""
519+msgstr "নিরাপত্তা লক"
517520
518521#: qml/Wizard/Pages/30-passwd-type.qml:74
519522msgid "Please select how you’d like to unlock your phone."
520−msgstr ""
523+msgstr "আপনি কিভাবে ফোনের লক খুলতে চান তা নির্ধারণ করুন।"
521524
522525#: qml/Wizard/Pages/30-passwd-type.qml:97
523526msgctxt "Label: Type of security method"
@@ -527,17 +530,17 @@ msgstr ""
527530#: qml/Wizard/Pages/30-passwd-type.qml:98
528531msgctxt "Label: Description of security method"
529532msgid "No security"
530−msgstr ""
533+msgstr "কোন নিরাপত্তা নেই"
531534
532535#: qml/Wizard/Pages/30-passwd-type.qml:100
533536msgctxt "Label: Type of security method"
534537msgid "Passcode"
535−msgstr ""
538+msgstr "পাসকোড"
536539
537540#: qml/Wizard/Pages/30-passwd-type.qml:101
538541msgctxt "Label: Description of security method"
539542msgid "4 digits only"
540−msgstr ""
543+msgstr "কেবল মাত্র ৪টি সংখ্যা"
541544
542545#: qml/Wizard/Pages/30-passwd-type.qml:103
543546msgctxt "Label: Type of security method"
@@ -660,3 +663,63 @@ msgstr ""
660663#, qt-format
661664msgid "%1 〉"
662665msgstr ""
666+
667+#~ msgid "Log out"
668+#~ msgstr "লগ অাউট"
669+
670+#~ msgid "Reboot"
671+#~ msgstr "পুনরায় চালু করুন"
672+
673+#~ msgid "Shut down"
674+#~ msgstr "বন্ধ করুন"
675+
676+#~ msgid "Power off"
677+#~ msgstr "বন্ধ করুন"
678+
679+#~ msgid "Restart"
680+#~ msgstr "পুনরায় চালু"
681+
682+#~ msgid "Top edge"
683+#~ msgstr "উপরের প্রান্ত"
684+
685+#~ msgid "Close"
686+#~ msgstr "বন্ধ"
687+
688+#~ msgid "Left edge"
689+#~ msgstr "বাম প্রান্ত"
690+
691+#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
692+#~ msgstr "অ্যাপসমূহে দ্রুত যাওয়ার লঞ্চার পেতে হলে বাম প্রান্ত থেকে সোয়াইপ করুন"
693+
694+#~ msgid "Well done"
695+#~ msgstr "অস্থির!"
696+
697+#~ msgid "Try swiping from the right edge to unlock the phone"
698+#~ msgstr "ফোনটির লক খুলতে ডান প্রান্ত থেকে সোয়াইপ করুন"
699+
700+#~ msgid "Right edge"
701+#~ msgstr "ডান প্রান্ত"
702+
703+#~ msgid "Settings"
704+#~ msgstr "সেটিংস"
705+
706+#~ msgid "Store"
707+#~ msgstr "স্টোর"
708+
709+#~ msgid "Search"
710+#~ msgstr "খুঁজুন"
711+
712+#~ msgid "Type or say a command"
713+#~ msgstr "কমান্ড লিখুন বা বলুন"
714+
715+#~ msgid "Loading. Please Wait..."
716+#~ msgstr "অপেক্ষা করুন..."
717+
718+#~ msgid "Speaking..."
719+#~ msgstr "বলা হচ্ছে..."
720+
721+#~ msgid "Speak Now..."
722+#~ msgstr "এখন বলুন..."
723+
724+#~ msgid "Please re-enter"
725+#~ msgstr "অনুগ্রহ করে আবার লিখুন"
po/br.po+38−19
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-10-05 06:47+0000\n"
11+"PO-Revision-Date: 2016-02-22 12:29+0000\n"
1212"Last-Translator: Fohanno Thierry <thierry.fohanno@ofis-bzh.org>\n"
1313"Language-Team: Breton <br@li.org>\n"
14+"Language: br\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -155,27 +156,29 @@ msgstr "Mat eo"
155156
156157#: qml/Components/ModeSwitchWarningDialog.qml:32
157158msgid "Apps may have unsaved data:"
158−msgstr ""
159+msgstr "Roadennoù ha n'int ket enrollet a c'hall bezañ gant an arloadoù :"
159160
160161#: qml/Components/ModeSwitchWarningDialog.qml:57
161162msgid "Re-dock, save your work and close these apps to continue."
162163msgstr ""
164+"Adlugit, enrollit ho labour ha serrit an arloadoù-mañ evit kenderc'hel."
163165
164166#: qml/Components/ModeSwitchWarningDialog.qml:63
165167msgid "Or force close now (unsaved data will be lost)."
166168msgstr ""
169+"Pe rediañ da serriñ bremañ (kollet e vo ar roadennoù n'int ket bet enrollet)."
167170
168171#: qml/Components/ModeSwitchWarningDialog.qml:75
169172msgid "OK, I will reconnect"
170−msgstr ""
173+msgstr "Mat eo, ez an da adkevreañ"
171174
172175#: qml/Components/ModeSwitchWarningDialog.qml:76
173176msgid "Reconnect now!"
174−msgstr ""
177+msgstr "Adkevreañ bremañ !"
175178
176179#: qml/Components/ModeSwitchWarningDialog.qml:88
177180msgid "Close all"
178−msgstr ""
181+msgstr "Serriñ pep tra"
179182
180183#: qml/Dash/DashPageHeader.qml:265
181184msgctxt "Button: Open the Ubuntu Store"
@@ -236,7 +239,7 @@ msgstr "Ouzhpennañ un ali"
236239
237240#: qml/Dash/Previews/PreviewSharing.qml:51
238241msgid "Preview Share Item"
239−msgstr ""
242+msgstr "Rakwelet an elfenn lodet"
240243
241244#: qml/Dash/PullToRefreshScopeStyle.qml:55
242245msgid "Pull to refresh…"
@@ -412,7 +415,7 @@ msgstr "C'hwitet, touchit evit adkregiñ"
412415#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
413416msgctxt "Button: Send a reply message"
414417msgid "Send"
415−msgstr ""
418+msgstr "Kas"
416419
417420#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
418421msgctxt "Label: Hint in message indicator line edit"
@@ -422,7 +425,7 @@ msgstr "Respont"
422425#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
423426msgctxt "Button: Call back on phone"
424427msgid "Call back"
425−msgstr ""
428+msgstr "Gervel en-dro"
426429
427430#: qml/Panel/Indicators/ModemInfoItem.qml:105
428431msgid "Unlock SIM"
@@ -527,8 +530,7 @@ msgstr "Surentez ar prennañ"
527530
528531#: qml/Wizard/Pages/30-passwd-type.qml:74
529532msgid "Please select how you’d like to unlock your phone."
530−msgstr ""
531−"Diuzit e peseurt mod e fell deoc'h dibrennañ ho pellgomzer, mar plij."
533+msgstr "Diuzit e peseurt mod e fell deoc'h dibrennañ ho pellgomzer, mar plij."
532534
533535#: qml/Wizard/Pages/30-passwd-type.qml:97
534536msgctxt "Label: Type of security method"
@@ -586,8 +588,7 @@ msgstr "Implijout ar GPS hepken (n'eo ket ken resis)"
586588
587589#: qml/Wizard/Pages/50-location.qml:86
588590msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
589−msgstr ""
590−"Implijout ar GPS, Wi-Fi dizanv pe titouroù ar rouedad kelligel (aliet)"
591+msgstr "Implijout ar GPS, Wi-Fi dizanv pe titouroù ar rouedad kelligel (aliet)"
591592
592593#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
593594#: qml/Wizard/Pages/50-location.qml:103
@@ -679,6 +680,22 @@ msgstr "〈 %1"
679680msgid "%1 〉"
680681msgstr "%1 〉"
681682
683+#~ msgid ""
684+#~ "Your device is now connected to an external display. Use this screen as a "
685+#~ "touch pad to interact with the mouse."
686+#~ msgstr ""
687+#~ "N'eo ket kevreet ho penveg ouzh un diskwel diavaez. Implijit ar skramm-"
688+#~ "mañ da douch evit ober gant al logodenn."
689+
690+#~ msgid "Welcome to your Ubuntu device."
691+#~ msgstr "Donemat en ho penveg Ubuntu"
692+
693+#~ msgid "Please select how you’d like to unlock your device."
694+#~ msgstr "Diuzit penaos e fell deoc'h dibrennañ ho penveg, mar plij."
695+
696+#~ msgid "Your device is now ready to use."
697+#~ msgstr "Prest eo ho penveg da vezañ implijet bremañ."
698+
682699#~ msgid "Close"
683700#~ msgstr "Serriñ"
684701
@@ -718,11 +735,13 @@ msgstr "%1 〉"
718735
719736#~ msgid "Try swiping from the top edge to access the indicators"
720737#~ msgstr ""
721−#~ "Lakait ho piz da riklañ adalek ar bord uhelañ da lakaat ar merkerioù war wel."
738+#~ "Lakait ho piz da riklañ adalek ar bord uhelañ da lakaat ar merkerioù war "
739+#~ "wel."
722740
723741#~ msgid "Swipe up again to close the settings screen"
724742#~ msgstr ""
725−#~ "Lakait ho piz da riklañ war-du ar bord uhelañ da serriñ skramm an arventennoù"
743+#~ "Lakait ho piz da riklañ war-du ar bord uhelañ da serriñ skramm an "
744+#~ "arventennoù"
726745
727746#~ msgid "Try swiping from the right edge to unlock the phone"
728747#~ msgstr ""
@@ -730,8 +749,8 @@ msgstr "%1 〉"
730749
731750#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
732751#~ msgstr ""
733−#~ "Lakait ho piz da riklañ adalek ar bord kleiz da ziskouez al lañser arloadoù "
734−#~ "prim."
752+#~ "Lakait ho piz da riklañ adalek ar bord kleiz da ziskouez al lañser "
753+#~ "arloadoù prim."
735754
736755#~ msgid "Well done"
737756#~ msgstr "Gourc'hemennoù !"
po/bs.po+6−5
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-12-01 20:06+0000\n"
1212"Last-Translator: Kenan Gutić <Unknown>\n"
1313"Language-Team: Bosnian <bs@li.org>\n"
14+"Language: bs\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
18+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
po/ca.po+20−13
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-04 09:48+0000\n"
1212"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
1313"Language-Team: Catalan <ca@li.org>\n"
14+"Language: ca\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -155,27 +156,29 @@ msgstr "D'acord"
155156
156157#: qml/Components/ModeSwitchWarningDialog.qml:32
157158msgid "Apps may have unsaved data:"
158−msgstr ""
159+msgstr "Pot ser que aquestes aplicacions no hagin desat les dades:"
159160
160161#: qml/Components/ModeSwitchWarningDialog.qml:57
161162msgid "Re-dock, save your work and close these apps to continue."
162163msgstr ""
164+"Torneu a connectar, deseu la feina i tanqueu aquestes aplicacions per "
165+"continuar."
163166
164167#: qml/Components/ModeSwitchWarningDialog.qml:63
165168msgid "Or force close now (unsaved data will be lost)."
166−msgstr ""
169+msgstr "O força el tancament (les dades no desades es perdran)."
167170
168171#: qml/Components/ModeSwitchWarningDialog.qml:75
169172msgid "OK, I will reconnect"
170−msgstr ""
173+msgstr "D'acord, tornaré a connectar"
171174
172175#: qml/Components/ModeSwitchWarningDialog.qml:76
173176msgid "Reconnect now!"
174−msgstr ""
177+msgstr "Torna a connectar"
175178
176179#: qml/Components/ModeSwitchWarningDialog.qml:88
177180msgid "Close all"
178−msgstr ""
181+msgstr "Tanca-ho tot"
179182
180183#: qml/Dash/DashPageHeader.qml:265
181184msgctxt "Button: Open the Ubuntu Store"
@@ -414,7 +417,7 @@ msgstr "Ha fallat, feu un toc per tornar-ho a intentar"
414417#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
415418msgctxt "Button: Send a reply message"
416419msgid "Send"
417−msgstr ""
420+msgstr "Envia"
418421
419422#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
420423msgctxt "Label: Hint in message indicator line edit"
@@ -424,7 +427,7 @@ msgstr "Respon"
424427#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
425428msgctxt "Button: Call back on phone"
426429msgid "Call back"
427−msgstr ""
430+msgstr "Retorna la trucada"
428431
429432#: qml/Panel/Indicators/ModemInfoItem.qml:105
430433msgid "Unlock SIM"
@@ -714,7 +717,8 @@ msgstr "%1 〉"
714717
715718#~ msgid "Try swiping from the top edge to access the indicators"
716719#~ msgstr ""
717−#~ "Proveu de lliscar el dit des de la vora superior per accedir als indicadors"
720+#~ "Proveu de lliscar el dit des de la vora superior per accedir als "
721+#~ "indicadors"
718722
719723#~ msgid "Close"
720724#~ msgstr "Tanca"
@@ -726,8 +730,8 @@ msgstr "%1 〉"
726730
727731#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
728732#~ msgstr ""
729−#~ "Llisqueu el dit des de la vora esquerra per mostrar el llançador i accedir "
730−#~ "ràpidament a les aplicacions"
733+#~ "Llisqueu el dit des de la vora esquerra per mostrar el llançador i "
734+#~ "accedir ràpidament a les aplicacions"
731735
732736#~ msgid "Skip intro"
733737#~ msgstr "Omet la introducció"
@@ -811,3 +815,6 @@ msgstr "%1 〉"
811815
812816#~ msgid "%l:%M %p"
813817#~ msgstr "%l∶%M %p"
818+
819+#~ msgid "Call back"
820+#~ msgstr "Retorna la trucada"
po/ca@valencia.po+9−8
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-02-22 15:22+0000\n"
1212"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
1313"Language-Team: Catalan <ca@li.org>\n"
14+"Language: ca\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -606,8 +607,7 @@ msgstr "No"
606607
607608#: qml/Wizard/Pages/50-location.qml:124
608609msgid "You can change your mind later in <b>System Settings</b>."
609−msgstr ""
610−"Podeu canviar-ho més avant a l'aplicació <b>Paràmetres del sistema</b>"
610+msgstr "Podeu canviar-ho més avant a l'aplicació <b>Paràmetres del sistema</b>"
611611
612612#: qml/Wizard/Pages/60-reporting.qml:26
613613msgid "Improving your experience"
@@ -715,7 +715,8 @@ msgstr "%1 〉"
715715
716716#~ msgid "Try swiping from the top edge to access the indicators"
717717#~ msgstr ""
718−#~ "Proveu de lliscar el dit des de la vora superior per accedir als indicadors"
718+#~ "Proveu de lliscar el dit des de la vora superior per accedir als "
719+#~ "indicadors"
719720
720721#~ msgid "Close"
721722#~ msgstr "Tanca"
@@ -730,8 +731,8 @@ msgstr "%1 〉"
730731
731732#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
732733#~ msgstr ""
733−#~ "Llisqueu el dit des de la vora esquerra per mostrar el llançador i accedir "
734−#~ "ràpidament a les aplicacions"
734+#~ "Llisqueu el dit des de la vora esquerra per mostrar el llançador i "
735+#~ "accedir ràpidament a les aplicacions"
735736
736737#~ msgid "Well done"
737738#~ msgstr "Enhorabona!"
po/ce.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-02-15 04:01+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Chechen <ce@li.org>\n"
14+"Language: ce\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/ckb.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-01-21 11:05+0000\n"
1212"Last-Translator: Aras <aras.noori@gmail.com>\n"
1313"Language-Team: Kurdish (Sorani) <ckb@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/cs.po+8−10
@@ -6,18 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-07 10:44+0000\n"
1212"Last-Translator: Vojtěch Daněk <vdanek@outlook.com>\n"
1313"Language-Team: Czech <cs@li.org>\n"
14+"Language: cs\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
20−"Language: cs\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2121
2222#: plugins/IntegratedLightDM/Greeter.cpp:112
2323msgid "Password: "
@@ -42,13 +42,11 @@ msgstr "Zařízení uzamčeno"
4242
4343#: qml/Components/DelayedLockscreen.qml:64
4444msgid "You have been locked out due to too many failed passphrase attempts."
45−msgstr ""
46−"Zařízení bylo uzamčeno z důvodu mnoha neúspěšných pokusů o přihlášení."
45+msgstr "Zařízení bylo uzamčeno z důvodu mnoha neúspěšných pokusů o přihlášení."
4746
4847#: qml/Components/DelayedLockscreen.qml:65
4948msgid "You have been locked out due to too many failed passcode attempts."
50−msgstr ""
51−"Zařízení bylo uzamčeno z důvodu mnoha neúspěšných pokusů o přihlášení."
49+msgstr "Zařízení bylo uzamčeno z důvodu mnoha neúspěšných pokusů o přihlášení."
5250
5351#: qml/Components/DelayedLockscreen.qml:74
5452#, qt-format
@@ -625,8 +623,8 @@ msgid ""
625623"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
626624"Privacy</b>"
627625msgstr ""
628−"To může být vypnuto v <b>Nastavení systému</b> v <b>Zabezpečení a "
629−"soukromí</b>"
626+"To může být vypnuto v <b>Nastavení systému</b> v <b>Zabezpečení a soukromí</"
627+"b>"
630628
631629#: qml/Wizard/Pages/80-finished.qml:24
632630msgid "All done"
po/cy.po+6−5
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-31 13:21+0000\n"
1212"Last-Translator: Owen Llywelyn <owen.llywelyn@gmail.com>\n"
1313"Language-Team: Welsh <cy@li.org>\n"
14+"Language: cy\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==2 ? 1 : (n != 8 && n != 11) ? "
1819"2 : 3;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -601,8 +602,8 @@ msgid ""
601602"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
602603"conditions</a>."
603604msgstr ""
604−"Drwy ddewis yr opsiwn yma rydych yn cytuno i <a href='#'>dermau ac "
605−"amodau</a> Nokia HERE."
605+"Drwy ddewis yr opsiwn yma rydych yn cytuno i <a href='#'>dermau ac amodau</"
606+"a> Nokia HERE."
606607
607608#: qml/Wizard/Pages/50-location.qml:112
608609msgid "Not at all"
po/da.po+8−6
@@ -7,17 +7,18 @@
77msgid ""
88msgstr ""
99"Project-Id-Version: unity8\n"
10−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"Report-Msgid-Bugs-To: \n"
1111"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1212"PO-Revision-Date: 2015-07-06 12:05+0000\n"
1313"Last-Translator: Folmer Fredslund <Unknown>\n"
1414"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
15+"Language: da\n"
1516"MIME-Version: 1.0\n"
1617"Content-Type: text/plain; charset=UTF-8\n"
1718"Content-Transfer-Encoding: 8bit\n"
1819"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -715,7 +716,8 @@ msgstr "%1 〉"
715716#~ msgstr "Stryg op igen for at låse indstillingsskærmen"
716717
717718#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
718−#~ msgstr "Stryg fra venstre for at vise opstarteren med hurtig adgang til apps"
719+#~ msgstr ""
720+#~ "Stryg fra venstre for at vise opstarteren med hurtig adgang til apps"
719721
720722#~ msgid "Well done"
721723#~ msgstr "Godt gjort"
@@ -733,8 +735,8 @@ msgstr "%1 〉"
733735#~ "You have now mastered the edge gestures and can start using the "
734736#~ "phone<br><br>Tap on the screen to start"
735737#~ msgstr ""
736−#~ "Du mestrer nu kantbevægelserne og kan begynde at bruge telefonen<br><br>Tryk "
737−#~ "på skærmen for at starte"
738+#~ "Du mestrer nu kantbevægelserne og kan begynde at bruge "
739+#~ "telefonen<br><br>Tryk på skærmen for at starte"
738740
739741#~ msgid "Please re-enter"
740742#~ msgstr "Vær venlig at genindtaste"
po/de.po+23−7
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-07-24 18:03+0000\n"
12−"Last-Translator: Torsten Franz <Unknown>\n"
11+"PO-Revision-Date: 2016-02-17 19:16+0000\n"
12+"Last-Translator: schuko24 <gerdsaenger@t-online.de>\n"
1313"Language-Team: German <de@li.org>\n"
14+"Language: de\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -444,8 +445,7 @@ msgstr "Wischen Sie von der unteren Bildschirmkante nach oben."
444445
445446#: qml/Tutorial/TutorialBottomFinish.qml:24
446447msgid "This action does different things for different apps"
447−msgstr ""
448−"Diese Aktion bewirkt verschiedene Dinge in verschiedenen Anwendungen."
448+msgstr "Diese Aktion bewirkt verschiedene Dinge in verschiedenen Anwendungen."
449449
450450#: qml/Tutorial/TutorialBottomFinish.qml:25
451451msgid "Tap here to finish."
@@ -682,6 +682,22 @@ msgstr "〈 %1"
682682msgid "%1 〉"
683683msgstr "%1 〉"
684684
685+#~ msgid ""
686+#~ "Your device is now connected to an external display. Use this screen as a "
687+#~ "touch pad to interact with the mouse."
688+#~ msgstr ""
689+#~ "Ihr Gerät ist nun mit einer externen Anzeige verbunden. Benutzen Sie "
690+#~ "diesen Bildschirm als Touchpad zur Steuerung des Mauszeigers."
691+
692+#~ msgid "Welcome to your Ubuntu device."
693+#~ msgstr "Willkommen auf Ihrem Ubuntu-Gerät."
694+
695+#~ msgid "Please select how you’d like to unlock your device."
696+#~ msgstr "Bitte wählen Sie, wie Sie dieses Gerät entsperren möchten."
697+
698+#~ msgid "Your device is now ready to use."
699+#~ msgstr "Ihr Gerät ist nun einsatzbereit."
700+
685701#~ msgid "Confirm"
686702#~ msgstr "Bestätigen"
687703
po/el.po+5−5
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-12-04 09:38+0000\n"
1212"Last-Translator: Aggelos Arnaoutis <angelosarn@hotmail.com>\n"
1313"Language-Team: Greek <el@li.org>\n"
14+"Language: el\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -446,8 +447,7 @@ msgstr "Σύρετε από την κάτω άκρη προς τα πάνω."
446447
447448#: qml/Tutorial/TutorialBottomFinish.qml:24
448449msgid "This action does different things for different apps"
449−msgstr ""
450−"Αυτή η ενέργεια κάνει διαφορετικά πράγματα για διαφορετικές εφαρμογές"
450+msgstr "Αυτή η ενέργεια κάνει διαφορετικά πράγματα για διαφορετικές εφαρμογές"
451451
452452#: qml/Tutorial/TutorialBottomFinish.qml:25
453453msgid "Tap here to finish."
po/en_AU.po+23−15
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-07-12 07:17+0000\n"
11+"PO-Revision-Date: 2016-02-12 23:22+0000\n"
1212"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
1313"Language-Team: English (Australia) <en_AU@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -29,7 +30,7 @@ msgstr "Pin shortcut"
2930
3031#: plugins/Unity/Launcher/launcheritem.cpp:52
3132msgid "Quit"
32−msgstr ""
33+msgstr "Quit"
3334
3435#: plugins/Unity/Launcher/launcheritem.cpp:106
3536msgid "Unpin shortcut"
@@ -151,27 +152,27 @@ msgstr "OK"
151152
152153#: qml/Components/ModeSwitchWarningDialog.qml:32
153154msgid "Apps may have unsaved data:"
154−msgstr ""
155+msgstr "Apps may have unsaved data:"
155156
156157#: qml/Components/ModeSwitchWarningDialog.qml:57
157158msgid "Re-dock, save your work and close these apps to continue."
158−msgstr ""
159+msgstr "Re-dock, save your work and close these apps to continue."
159160
160161#: qml/Components/ModeSwitchWarningDialog.qml:63
161162msgid "Or force close now (unsaved data will be lost)."
162−msgstr ""
163+msgstr "Or force close now (unsaved data will be lost)."
163164
164165#: qml/Components/ModeSwitchWarningDialog.qml:75
165166msgid "OK, I will reconnect"
166−msgstr ""
167+msgstr "OK, I will reconnect"
167168
168169#: qml/Components/ModeSwitchWarningDialog.qml:76
169170msgid "Reconnect now!"
170−msgstr ""
171+msgstr "Reconnect now!"
171172
172173#: qml/Components/ModeSwitchWarningDialog.qml:88
173174msgid "Close all"
174−msgstr ""
175+msgstr "Close all"
175176
176177#: qml/Dash/DashPageHeader.qml:265
177178msgctxt "Button: Open the Ubuntu Store"
@@ -232,7 +233,7 @@ msgstr "Add a review"
232233
233234#: qml/Dash/Previews/PreviewSharing.qml:51
234235msgid "Preview Share Item"
235−msgstr ""
236+msgstr "Preview Share Item"
236237
237238#: qml/Dash/PullToRefreshScopeStyle.qml:55
238239msgid "Pull to refresh…"
@@ -327,7 +328,7 @@ msgstr "Sorry, incorrect passphrase"
327328#: qml/Greeter/NarrowView.qml:121
328329msgctxt "passphrase"
329330msgid "Please re-enter"
330−msgstr ""
331+msgstr "Please re-enter"
331332
332333#: qml/Greeter/NarrowView.qml:122
333334msgid "Sorry, incorrect passcode"
@@ -408,7 +409,7 @@ msgstr "Failed, tap to retry"
408409#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
409410msgctxt "Button: Send a reply message"
410411msgid "Send"
411−msgstr ""
412+msgstr "Send"
412413
413414#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
414415msgctxt "Label: Hint in message indicator line edit"
@@ -418,7 +419,7 @@ msgstr "Reply"
418419#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
419420msgctxt "Button: Call back on phone"
420421msgid "Call back"
421−msgstr ""
422+msgstr "Call back"
422423
423424#: qml/Panel/Indicators/ModemInfoItem.qml:105
424425msgid "Unlock SIM"
@@ -673,6 +674,13 @@ msgstr "〈 %1"
673674msgid "%1 〉"
674675msgstr "%1 〉"
675676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "Your device is now connected to an external display. Use this screen as a "
682+#~ "touch pad to interact with the mouse."
683+
676684#~ msgid "Confirm"
677685#~ msgstr "Confirm"
678686
po/en_GB.po+26−9
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-04-23 12:59+0000\n"
1212"Last-Translator: Andi Chandler <Unknown>\n"
1313"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -151,27 +152,27 @@ msgstr "OK"
151152
152153#: qml/Components/ModeSwitchWarningDialog.qml:32
153154msgid "Apps may have unsaved data:"
154−msgstr ""
155+msgstr "Apps may have unsaved data:"
155156
156157#: qml/Components/ModeSwitchWarningDialog.qml:57
157158msgid "Re-dock, save your work and close these apps to continue."
158−msgstr ""
159+msgstr "Re-dock, save your work and close these apps to continue."
159160
160161#: qml/Components/ModeSwitchWarningDialog.qml:63
161162msgid "Or force close now (unsaved data will be lost)."
162−msgstr ""
163+msgstr "Or force close now (unsaved data will be lost)."
163164
164165#: qml/Components/ModeSwitchWarningDialog.qml:75
165166msgid "OK, I will reconnect"
166−msgstr ""
167+msgstr "OK, I will reconnect"
167168
168169#: qml/Components/ModeSwitchWarningDialog.qml:76
169170msgid "Reconnect now!"
170−msgstr ""
171+msgstr "Reconnect now!"
171172
172173#: qml/Components/ModeSwitchWarningDialog.qml:88
173174msgid "Close all"
174−msgstr ""
175+msgstr "Close all"
175176
176177#: qml/Dash/DashPageHeader.qml:265
177178msgctxt "Button: Open the Ubuntu Store"
@@ -673,6 +674,22 @@ msgstr "〈 %1"
673674msgid "%1 〉"
674675msgstr "%1 〉"
675676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "Your device is now connected to an external display. Use this screen as a "
682+#~ "touch pad to interact with the mouse."
683+
684+#~ msgid "Welcome to your Ubuntu device."
685+#~ msgstr "Welcome to your Ubuntu device."
686+
687+#~ msgid "Please select how you’d like to unlock your device."
688+#~ msgstr "Please select how you would like to unlock your device."
689+
690+#~ msgid "Your device is now ready to use."
691+#~ msgstr "Your device is now ready to use."
692+
676693#~ msgid "Confirm"
677694#~ msgstr "Confirm"
678695
po/eo.po+44−43
@@ -6,21 +6,22 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-06-06 23:37+0000\n"
1212"Last-Translator: Eliovir <Unknown>\n"
1313"Language-Team: Esperanto <eo@li.org>\n"
14+"Language: eo\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
23−msgstr ""
24+msgstr "Pasvorto: "
2425
2526#: plugins/Unity/Launcher/launcheritem.cpp:47
2627#: plugins/Unity/Launcher/launcheritem.cpp:106
@@ -57,26 +58,26 @@ msgstr[1] ""
5758#: qml/Components/Dialogs.qml:144
5859msgctxt "Title: Lock/Log out dialog"
5960msgid "Log out"
60−msgstr ""
61+msgstr "Elsaluti"
6162
6263#: qml/Components/Dialogs.qml:145
6364msgid "Are you sure you want to log out?"
64−msgstr ""
65+msgstr "Ĉu vi certas, ke vi volas elsaluti?"
6566
6667#: qml/Components/Dialogs.qml:147
6768msgctxt "Button: Lock the system"
6869msgid "Lock"
69−msgstr ""
70+msgstr "Ŝlosi"
7071
7172#: qml/Components/Dialogs.qml:154
7273msgctxt "Button: Log out from the system"
7374msgid "Log Out"
74−msgstr ""
75+msgstr "Elsaluti"
7576
7677#: qml/Components/Dialogs.qml:161 qml/Components/Dialogs.qml:194
7778#: qml/Components/Dialogs.qml:253
7879msgid "Cancel"
79−msgstr ""
80+msgstr "Nuligi"
8081
8182#: qml/Components/Dialogs.qml:173
8283msgctxt "Title: Reboot/Shut down dialog"
@@ -108,16 +109,16 @@ msgstr ""
108109
109110#: qml/Components/Dialogs.qml:210
110111msgid "No"
111−msgstr ""
112+msgstr "Ne"
112113
113114#: qml/Components/Dialogs.qml:217
114115msgid "Yes"
115−msgstr ""
116+msgstr "Jes"
116117
117118#: qml/Components/Dialogs.qml:232
118119msgctxt "Title: Power off/Restart dialog"
119120msgid "Power"
120−msgstr ""
121+msgstr "Energio"
121122
122123#: qml/Components/Dialogs.qml:233
123124msgid ""
@@ -145,7 +146,7 @@ msgstr ""
145146
146147#: qml/Components/Lockscreen.qml:277
147148msgid "OK"
148−msgstr ""
149+msgstr "Bone"
149150
150151#: qml/Components/ModeSwitchWarningDialog.qml:32
151152msgid "Apps may have unsaved data:"
@@ -179,12 +180,12 @@ msgstr ""
179180#: qml/Dash/DashPageHeader.qml:272
180181msgctxt "Button: Start a search in the current dash scope"
181182msgid "Search"
182−msgstr ""
183+msgstr "Serĉi"
183184
184185#: qml/Dash/DashPageHeader.qml:282
185186msgctxt "Button: Show the current dash scope settings"
186187msgid "Settings"
187−msgstr ""
188+msgstr "Agordoj"
188189
189190#: qml/Dash/DashPageHeader.qml:289
190191msgid "Remove from Favorites"
@@ -192,7 +193,7 @@ msgstr ""
192193
193194#: qml/Dash/DashPageHeader.qml:289
194195msgid "Add to Favorites"
195−msgstr ""
196+msgstr "Aldoni al favoritoj"
196197
197198#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
198199msgid "See less"
@@ -205,11 +206,11 @@ msgstr ""
205206#: qml/Dash/GenericScopeView.qml:638
206207msgctxt "Label: Hint for dash search line edit"
207208msgid "Search"
208−msgstr ""
209+msgstr "Serĉi"
209210
210211#: qml/Dash/Previews/PreviewActionCombo.qml:35
211212msgid "More..."
212−msgstr ""
213+msgstr "Pli…"
213214
214215#: qml/Dash/Previews/PreviewActionCombo.qml:35
215216msgid "Less..."
@@ -262,11 +263,11 @@ msgstr ""
262263
263264#: qml/Greeter/CoverPage.qml:107
264265msgid "Unlock"
265−msgstr ""
266+msgstr "Malŝlosi"
266267
267268#: qml/Greeter/LoginList.qml:236
268269msgid "Retry"
269−msgstr ""
270+msgstr "Reprovi"
270271
271272#: qml/Greeter/LoginList.qml:237
272273msgid "Tap to unlock"
@@ -347,32 +348,32 @@ msgstr ""
347348#, qt-format
348349msgid "%1 hour"
349350msgid_plural "%1 hours"
350−msgstr[0] ""
351−msgstr[1] ""
351+msgstr[0] "%1 horo"
352+msgstr[1] "%1 horoj"
352353
353354#: qml/Panel/Indicators/MenuItemFactory.qml:864
354355#, qt-format
355356msgid "%1 minute"
356357msgid_plural "%1 minutes"
357−msgstr[0] ""
358−msgstr[1] ""
358+msgstr[0] "%1 minuto"
359+msgstr[1] "%1 minutoj"
359360
360361#: qml/Panel/Indicators/MenuItemFactory.qml:869
361362#, qt-format
362363msgid "%1 second"
363364msgid_plural "%1 seconds"
364−msgstr[0] ""
365−msgstr[1] ""
365+msgstr[0] "%1 sekundo"
366+msgstr[1] "%1 sekundoj"
366367
367368#: qml/Panel/Indicators/MenuItemFactory.qml:872
368369msgid "0 seconds"
369−msgstr ""
370+msgstr "0 sekundoj"
370371
371372#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
372373#: qml/Panel/Indicators/MenuItemFactory.qml:874
373374#, qt-format
374375msgid "%1 remaining"
375−msgstr ""
376+msgstr "%1 restas"
376377
377378#: qml/Panel/Indicators/MenuItemFactory.qml:880
378379msgid "In queue…"
@@ -388,11 +389,11 @@ msgstr ""
388389
389390#: qml/Panel/Indicators/MenuItemFactory.qml:888
390391msgid "Canceled"
391−msgstr ""
392+msgstr "Nuligita"
392393
393394#: qml/Panel/Indicators/MenuItemFactory.qml:890
394395msgid "Finished"
395−msgstr ""
396+msgstr "Finita"
396397
397398#: qml/Panel/Indicators/MenuItemFactory.qml:892
398399msgid "Failed, tap to retry"
@@ -402,12 +403,12 @@ msgstr ""
402403#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
403404msgctxt "Button: Send a reply message"
404405msgid "Send"
405−msgstr ""
406+msgstr "Sendi"
406407
407408#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
408409msgctxt "Label: Hint in message indicator line edit"
409410msgid "Reply"
410−msgstr ""
411+msgstr "Respondi"
411412
412413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
413414msgctxt "Button: Call back on phone"
@@ -420,7 +421,7 @@ msgstr ""
420421
421422#: qml/Panel/Indicators/RoamingIndication.qml:27
422423msgid "Roaming"
423−msgstr ""
424+msgstr "Retmigrado"
424425
425426#: qml/Tutorial/TutorialBottom.qml:28
426427msgid "Open special menus"
@@ -461,7 +462,7 @@ msgstr ""
461462
462463#: qml/Tutorial/TutorialPage.qml:195
463464msgid "Try again."
464−msgstr ""
465+msgstr "Reprovu."
465466
466467#: qml/Tutorial/TutorialRight.qml:31
467468msgid "To view open apps"
@@ -478,15 +479,15 @@ msgstr ""
478479#: qml/Wizard/Page.qml:89
479480msgctxt "Button: Go back one page in the Wizard"
480481msgid "Back"
481−msgstr ""
482+msgstr "Reen"
482483
483484#: qml/Wizard/Pages/10-welcome.qml:27
484485msgid "Hi!"
485−msgstr ""
486+msgstr "Saluton!"
486487
487488#: qml/Wizard/Pages/10-welcome.qml:44
488489msgid "Welcome to your Ubuntu phone."
489−msgstr ""
490+msgstr "Bonvenon al via Ubuntu-telefono."
490491
491492#: qml/Wizard/Pages/10-welcome.qml:52
492493msgid "Let’s get started."
@@ -497,7 +498,7 @@ msgstr ""
497498#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
498499#: qml/Wizard/Pages/passwd-set.qml:90
499500msgid "Continue"
500−msgstr ""
501+msgstr "Daŭrigi"
501502
502503#: qml/Wizard/Pages/20-sim.qml:25
503504msgid "Add a SIM card and restart your device"
@@ -551,7 +552,7 @@ msgstr ""
551552
552553#: qml/Wizard/Pages/40-wifi.qml:29
553554msgid "Connect to Wi‑Fi"
554−msgstr ""
555+msgstr "Konekti al sendrata reto"
555556
556557#: qml/Wizard/Pages/40-wifi.qml:168
557558msgid "Available networks…"
@@ -563,7 +564,7 @@ msgstr ""
563564
564565#: qml/Wizard/Pages/50-location.qml:27
565566msgid "Location"
566−msgstr ""
567+msgstr "Loko"
567568
568569#: qml/Wizard/Pages/50-location.qml:62
569570msgid "Let the phone detect your location:"
@@ -639,7 +640,7 @@ msgstr ""
639640#: qml/Wizard/Pages/passwd-confirm.qml:53
640641#: qml/Wizard/Pages/passwd-confirm.qml:54
641642msgid "Please try again."
642−msgstr ""
643+msgstr "Reprovu."
643644
644645#: qml/Wizard/Pages/passwd-set.qml:61
645646msgid "Choose your passcode"
@@ -653,10 +654,10 @@ msgstr ""
653654#: qml/Wizard/StackButton.qml:39
654655#, qt-format
655656msgid "〈 %1"
656−msgstr ""
657+msgstr "〈 %1"
657658
658659#. Translators: This is the arrow for "Forward" buttons
659660#: qml/Wizard/StackButton.qml:42
660661#, qt-format
661662msgid "%1 〉"
662−msgstr ""
663+msgstr "%1 〉"
po/es.po+26−7
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-07-04 06:08+0000\n"
12−"Last-Translator: Paco Molinero <paco@byasl.com>\n"
11+"PO-Revision-Date: 2016-01-15 14:48+0000\n"
12+"Last-Translator: Víctor R. Ruiz <Unknown>\n"
1313"Language-Team: Spanish <es@li.org>\n"
14+"Language: es\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -160,6 +161,8 @@ msgstr "Las aplicaciones podrían tener datos sin guardar."
160161#: qml/Components/ModeSwitchWarningDialog.qml:57
161162msgid "Re-dock, save your work and close these apps to continue."
162163msgstr ""
164+"Re-acople el dispositivo, guarde el trabajo y cierre estas aplicaciones para "
165+"continuar."
163166
164167#: qml/Components/ModeSwitchWarningDialog.qml:63
165168msgid "Or force close now (unsaved data will be lost)."
@@ -677,6 +680,22 @@ msgstr "〈 %1"
677680msgid "%1 〉"
678681msgstr "%1 〉"
679682
683+#~ msgid ""
684+#~ "Your device is now connected to an external display. Use this screen as a "
685+#~ "touch pad to interact with the mouse."
686+#~ msgstr ""
687+#~ "Ahora está conectado a una pantalla externa. Utilice esta pantalla como "
688+#~ "dispositivo táctil para controlar el ratón."
689+
690+#~ msgid "Welcome to your Ubuntu device."
691+#~ msgstr "Bienvenido a su dispositivo Ubuntu."
692+
693+#~ msgid "Please select how you’d like to unlock your device."
694+#~ msgstr "Por favor, seleccione cómo desea desbloquear el dispositivo."
695+
696+#~ msgid "Your device is now ready to use."
697+#~ msgstr "El dispositivo ya está listo."
698+
680699#~ msgid "Confirm"
681700#~ msgstr "Confirmar"
682701
@@ -732,8 +751,8 @@ msgstr "%1 〉"
732751#~ "You have now mastered the edge gestures and can start using the "
733752#~ "phone<br><br>Tap on the screen to start"
734753#~ msgstr ""
735−#~ "Ahora domina los gestos de los bordes y puede usar el teléfono<br><br>Toque "
736−#~ "la pantalla para comenzar"
754+#~ "Ahora domina los gestos de los bordes y puede usar el "
755+#~ "teléfono<br><br>Toque la pantalla para comenzar"
737756
738757#~ msgid "Power off"
739758#~ msgstr "Apagar"
po/eu.po+6−5
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-13 23:29+0000\n"
1212"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
1313"Language-Team: Basque <eu@li.org>\n"
14+"Language: eu\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -761,8 +762,8 @@ msgstr "%1 〉"
761762
762763#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
763764#~ msgstr ""
764−#~ "Pasatu hatza ezkerretik abiarazlea erakutsi eta aplikazioak berehala eskura "
765−#~ "izateko"
765+#~ "Pasatu hatza ezkerretik abiarazlea erakutsi eta aplikazioak berehala "
766+#~ "eskura izateko"
766767
767768#~ msgid "Confirm"
768769#~ msgstr "Berretsi"
po/fa.po+10−13
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-11 15:43+0000\n"
1212"Last-Translator: Danial Behzadi <dani.behzi@gmail.com>\n"
1313"Language-Team: Persian <fa@li.org>\n"
14+"Language: fa\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -41,8 +42,7 @@ msgstr "دستگاه قفل شد"
4142
4243#: qml/Components/DelayedLockscreen.qml:64
4344msgid "You have been locked out due to too many failed passphrase attempts."
44−msgstr ""
45−"شما به دلیل تلاش‌های بسیار زیاد شکست خورده برای عبارت‌عبور قفل شده‌اید."
45+msgstr "شما به دلیل تلاش‌های بسیار زیاد شکست خورده برای عبارت‌عبور قفل شده‌اید."
4646
4747#: qml/Components/DelayedLockscreen.qml:65
4848msgid "You have been locked out due to too many failed passcode attempts."
@@ -509,8 +509,7 @@ msgstr "سیم‌کارتی افزوده و دستگاهتان را شروع م
509509
510510#: qml/Wizard/Pages/20-sim.qml:59
511511msgid "Without it, you won’t be able to make calls or use text messaging."
512−msgstr ""
513−"بدون آن، نخواهید توانست تماس گرفته با از پیام‌رسانی متنی استفاده کنید."
512+msgstr "بدون آن، نخواهید توانست تماس گرفته با از پیام‌رسانی متنی استفاده کنید."
514513
515514#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
516515msgid "Skip"
@@ -580,8 +579,7 @@ msgstr "فقط با استفاده از جی‌پی‌اس (دقّت کم‌تر
580579
581580#: qml/Wizard/Pages/50-location.qml:86
582581msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
583−msgstr ""
584−"با استفاده از جی‌پی‌اس، بی‌سیم ناشناس و اطّلاعات شبکه‌ی سلّولی (پیشنهاد شده)"
582+msgstr "با استفاده از جی‌پی‌اس، بی‌سیم ناشناس و اطّلاعات شبکه‌ی سلّولی (پیشنهاد شده)"
585583
586584#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
587585#: qml/Wizard/Pages/50-location.qml:103
@@ -617,8 +615,7 @@ msgid ""
617615"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
618616"Privacy</b>"
619617msgstr ""
620−"این می‌تواند در <b>تنظیمات سامانه</b> ذیل <b>امنیت و محرمانگی</b> غیرفعَال "
621−"شود"
618+"این می‌تواند در <b>تنظیمات سامانه</b> ذیل <b>امنیت و محرمانگی</b> غیرفعَال شود"
622619
623620#: qml/Wizard/Pages/80-finished.qml:24
624621msgid "All done"
@@ -710,8 +707,8 @@ msgstr "%1 〉"
710707#~ "You have now mastered the edge gestures and can start using the "
711708#~ "phone<br><br>Tap on the screen to start"
712709#~ msgstr ""
713−#~ "هم اکنون در استفاده از ژست های حرکتی مهارت لازم را دارید و می‌توانید استفاده "
714−#~ "از تلفن را آغاز کنید<br><br>برای شروع صفحه را لمس کنید"
710+#~ "هم اکنون در استفاده از ژست های حرکتی مهارت لازم را دارید و می‌توانید "
711+#~ "استفاده از تلفن را آغاز کنید<br><br>برای شروع صفحه را لمس کنید"
715712
716713#~ msgid "Confirm"
717714#~ msgstr "تأیید"
po/fi.po+21−5
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-04 18:32+0000\n"
1212"Last-Translator: Jiri Grönroos <Unknown>\n"
1313"Language-Team: Finnish <fi@li.org>\n"
14+"Language: fi\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -46,8 +47,7 @@ msgstr ""
4647
4748#: qml/Components/DelayedLockscreen.qml:65
4849msgid "You have been locked out due to too many failed passcode attempts."
49−msgstr ""
50−"Laite on lukittu liian monen virheellisen suojakoodiyrityksen jälkeen."
50+msgstr "Laite on lukittu liian monen virheellisen suojakoodiyrityksen jälkeen."
5151
5252#: qml/Components/DelayedLockscreen.qml:74
5353#, qt-format
@@ -678,6 +678,22 @@ msgstr "〈 %1"
678678msgid "%1 〉"
679679msgstr "%1 〉"
680680
681+#~ msgid ""
682+#~ "Your device is now connected to an external display. Use this screen as a "
683+#~ "touch pad to interact with the mouse."
684+#~ msgstr ""
685+#~ "Laitteesi on nyt yhdistetty erilliseen näyttöön. Käytä tätä näyttöä "
686+#~ "kosketuslevynä vaikuttaaksesi hiiren toimintaan."
687+
688+#~ msgid "Welcome to your Ubuntu device."
689+#~ msgstr "Tervetuloa Ubuntu-laitteesi pariin."
690+
691+#~ msgid "Please select how you’d like to unlock your device."
692+#~ msgstr "Valitse kuinka haluat avata laitteen lukituksen."
693+
694+#~ msgid "Your device is now ready to use."
695+#~ msgstr "Laitteesi on nyt valmis käytettäväksi."
696+
681697#~ msgid "Confirm"
682698#~ msgstr "Hyväksy"
683699
po/fo.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-01-14 20:08+0000\n"
1212"Last-Translator: Jógvan Olsen <jeggy@jebster.net>\n"
1313"Language-Team: Faroese <fo@li.org>\n"
14+"Language: fo\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/fr.po+29−8
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-11-07 19:43+0000\n"
12−"Last-Translator: Jean-Marc <Unknown>\n"
11+"PO-Revision-Date: 2016-02-28 17:22+0000\n"
12+"Last-Translator: Anne <anneonyme017@gmail.com>\n"
1313"Language-Team: French <fr@li.org>\n"
14+"Language: fr\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-29 05:58+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -160,6 +161,8 @@ msgstr "Les applications peuvent avoir des données non enregistrées :"
160161#: qml/Components/ModeSwitchWarningDialog.qml:57
161162msgid "Re-dock, save your work and close these apps to continue."
162163msgstr ""
164+"Rebranchez-vous sur la station d'accueil, enregistrez votre travail et "
165+"fermez ces applications pour continuer."
163166
164167#: qml/Components/ModeSwitchWarningDialog.qml:63
165168msgid "Or force close now (unsaved data will be lost)."
@@ -169,7 +172,7 @@ msgstr ""
169172
170173#: qml/Components/ModeSwitchWarningDialog.qml:75
171174msgid "OK, I will reconnect"
172−msgstr ""
175+msgstr "OK, je vais me reconnecter"
173176
174177#: qml/Components/ModeSwitchWarningDialog.qml:76
175178msgid "Reconnect now!"
@@ -687,6 +690,24 @@ msgstr "〈 %1"
687690msgid "%1 〉"
688691msgstr "%1 〉"
689692
693+#~ msgid ""
694+#~ "Your device is now connected to an external display. Use this screen as a "
695+#~ "touch pad to interact with the mouse."
696+#~ msgstr ""
697+#~ "Votre appareil est maintenant connecté à un affichage externe. Utilisez "
698+#~ "cet écran comme un pavé tactile pour interagir avec la souris."
699+
700+#~ msgid "Welcome to your Ubuntu device."
701+#~ msgstr "Bienvenue sur votre appareil Ubuntu."
702+
703+#~ msgid "Please select how you’d like to unlock your device."
704+#~ msgstr ""
705+#~ "Veuillez sélectionner la façon dont vous souhaitez déverrouiller votre "
706+#~ "appareil."
707+
708+#~ msgid "Your device is now ready to use."
709+#~ msgstr "Votre appareil est maintenant prêt à être utilisé."
710+
690711#~ msgid "Skip intro"
691712#~ msgstr "Passer l'intro"
692713
@@ -746,8 +767,8 @@ msgstr "%1 〉"
746767
747768#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
748769#~ msgstr ""
749−#~ "Faites glisser votre doigt à partir du bord gauche pour afficher le lanceur "
750−#~ "d'applications."
770+#~ "Faites glisser votre doigt à partir du bord gauche pour afficher le "
771+#~ "lanceur d'applications."
751772
752773#~ msgid "Power off"
753774#~ msgstr "Éteindre"
po/ga.po+137−120
@@ -6,53 +6,55 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-12-17 16:56+0000\n"
11+"PO-Revision-Date: 2016-01-25 11:33+0000\n"
1212"Last-Translator: Joshua Kiley <Unknown>\n"
1313"Language-Team: Irish <ga@li.org>\n"
14+"Language: ga\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n"
18−"X-Launchpad-Export-Date: 2015-12-18 05:51+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
23−msgstr "Focal Faire: "
24+msgstr "Pasfhocal "
2425
2526#: plugins/Unity/Launcher/launcheritem.cpp:47
2627#: plugins/Unity/Launcher/launcheritem.cpp:106
2728msgid "Pin shortcut"
28−msgstr ""
29+msgstr "Cruthaigh Aicearra Leis An Bharra"
2930
3031#: plugins/Unity/Launcher/launcheritem.cpp:52
3132msgid "Quit"
32−msgstr "Scoir"
33+msgstr "Éirigh as"
3334
3435#: plugins/Unity/Launcher/launcheritem.cpp:106
3536msgid "Unpin shortcut"
36−msgstr ""
37+msgstr "Bain Aicearra Den Bharra"
3738
3839#: qml/Components/DelayedLockscreen.qml:49
3940msgid "Device Locked"
40−msgstr ""
41+msgstr "Faoi Ghlas"
4142
4243#: qml/Components/DelayedLockscreen.qml:64
4344msgid "You have been locked out due to too many failed passphrase attempts."
44−msgstr ""
45+msgstr "Tá tú dúnta amach ceal an iomarca drochiarrachtaí pasfhocail."
4546
4647#: qml/Components/DelayedLockscreen.qml:65
4748msgid "You have been locked out due to too many failed passcode attempts."
48−msgstr ""
49+msgstr "Tá tú dúnta amach ceal an iomarca drochiarrachtaí cóid."
4950
5051#: qml/Components/DelayedLockscreen.qml:74
5152#, qt-format
5253msgid "Please wait %1 minute and then try again…"
5354msgid_plural "Please wait %1 minutes and then try again…"
54−msgstr[0] ""
55−msgstr[1] ""
55+msgstr[0] "Fan %1 nóiméad agus bain triail as arís, le do thoil."
56+msgstr[1] "Fan %1 nóiméad agus bain triail as arís, le do thoil."
57+msgstr[2] "Fan %1 nóiméad agus bain triail as arís, le do thoil."
5658
5759#: qml/Components/Dialogs.qml:144
5860msgctxt "Title: Lock/Log out dialog"
@@ -61,12 +63,12 @@ msgstr "Logáil Amach"
6163
6264#: qml/Components/Dialogs.qml:145
6365msgid "Are you sure you want to log out?"
64−msgstr ""
66+msgstr "An bhfuil tú cinnte gur mhaith leat lógáil amach?"
6567
6668#: qml/Components/Dialogs.qml:147
6769msgctxt "Button: Lock the system"
6870msgid "Lock"
69−msgstr "Glasáil"
71+msgstr "Cuir Faoi Ghlas"
7072
7173#: qml/Components/Dialogs.qml:154
7274msgctxt "Button: Log out from the system"
@@ -85,7 +87,7 @@ msgstr "Múch"
8587
8688#: qml/Components/Dialogs.qml:174
8789msgid "Are you sure you want to shut down?"
88−msgstr ""
90+msgstr "Cinnte gur mhaith leat an gléas a mhúchadh?"
8991
9092#: qml/Components/Dialogs.qml:176
9193msgctxt "Button: Reboot the system"
@@ -104,7 +106,7 @@ msgstr "Atosaigh"
104106
105107#: qml/Components/Dialogs.qml:208
106108msgid "Are you sure you want to reboot?"
107−msgstr ""
109+msgstr "Cinnte gur mhaith leat atosú?"
108110
109111#: qml/Components/Dialogs.qml:210
110112msgid "No"
@@ -112,18 +114,18 @@ msgstr "Níl"
112114
113115#: qml/Components/Dialogs.qml:217
114116msgid "Yes"
115−msgstr "Tá Go Maith"
117+msgstr "Tá"
116118
117119#: qml/Components/Dialogs.qml:232
118120msgctxt "Title: Power off/Restart dialog"
119121msgid "Power"
120−msgstr "Cumhacht"
122+msgstr "Múch an chumhacht"
121123
122124#: qml/Components/Dialogs.qml:233
123125msgid ""
124126"Are you sure you would like\n"
125127"to power off?"
126−msgstr ""
128+msgstr "Cinnte gur mhaith leat an chumhacht a mhúchadh?"
127129
128130#: qml/Components/Dialogs.qml:235
129131msgctxt "Button: Power off the system"
@@ -137,11 +139,11 @@ msgstr "Atosaigh"
137139
138140#: qml/Components/Lockscreen.qml:245
139141msgid "Return to Call"
140−msgstr ""
142+msgstr "Fill ar an Ghlaoch"
141143
142144#: qml/Components/Lockscreen.qml:245
143145msgid "Emergency Call"
144−msgstr ""
146+msgstr "Glaoch Éigeandála"
145147
146148#: qml/Components/Lockscreen.qml:277
147149msgid "OK"
@@ -149,11 +151,13 @@ msgstr "Tá Go Maith"
149151
150152#: qml/Components/ModeSwitchWarningDialog.qml:32
151153msgid "Apps may have unsaved data:"
152−msgstr ""
154+msgstr "Seans go mbeidh sonraí gan sábháil ag aipeanna:"
153155
154156#: qml/Components/ModeSwitchWarningDialog.qml:57
155157msgid "Re-dock, save your work and close these apps to continue."
156158msgstr ""
159+"Cuir sa leaba nasctha, sabhail do chuid oibre agus dún na haipeanna seo chun "
160+"leanúínt ar aghaidh."
157161
158162#: qml/Components/ModeSwitchWarningDialog.qml:63
159163msgid "Or force close now (unsaved data will be lost)."
@@ -161,11 +165,11 @@ msgstr ""
161165
162166#: qml/Components/ModeSwitchWarningDialog.qml:75
163167msgid "OK, I will reconnect"
164−msgstr ""
168+msgstr "Go maith, athcheanglóidh mé."
165169
166170#: qml/Components/ModeSwitchWarningDialog.qml:76
167171msgid "Reconnect now!"
168−msgstr ""
172+msgstr "Athnasc anois!"
169173
170174#: qml/Components/ModeSwitchWarningDialog.qml:88
171175msgid "Close all"
@@ -184,7 +188,7 @@ msgstr "Cuardach"
184188#: qml/Dash/DashPageHeader.qml:282
185189msgctxt "Button: Show the current dash scope settings"
186190msgid "Settings"
187−msgstr ""
191+msgstr "Socruithe"
188192
189193#: qml/Dash/DashPageHeader.qml:289
190194msgid "Remove from Favorites"
@@ -196,16 +200,16 @@ msgstr "Cuir le Ceanáin"
196200
197201#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
198202msgid "See less"
199−msgstr "Fheiceáil Níos Lú"
203+msgstr "Taispeáin níos lú"
200204
201205#: qml/Dash/GenericScopeView.qml:576
202206msgid "See all"
203−msgstr ""
207+msgstr "Taispeáin gach rud"
204208
205209#: qml/Dash/GenericScopeView.qml:638
206210msgctxt "Label: Hint for dash search line edit"
207211msgid "Search"
208−msgstr ""
212+msgstr "Cuardach"
209213
210214#: qml/Dash/Previews/PreviewActionCombo.qml:35
211215msgid "More..."
@@ -213,7 +217,7 @@ msgstr "Tuilleadh..."
213217
214218#: qml/Dash/Previews/PreviewActionCombo.qml:35
215219msgid "Less..."
216−msgstr ""
220+msgstr "Níos lú..."
217221
218222#: qml/Dash/Previews/PreviewCommentInput.qml:68
219223#: qml/Dash/Previews/PreviewRatingInput.qml:174
@@ -222,31 +226,31 @@ msgstr "Seol"
222226
223227#: qml/Dash/Previews/PreviewRatingInput.qml:84
224228msgid "Rate this"
225−msgstr ""
229+msgstr "Grádaigh é seo"
226230
227231#: qml/Dash/Previews/PreviewRatingInput.qml:129
228232msgid "Add a review"
229−msgstr ""
233+msgstr "Cuir léirmheas leis"
230234
231235#: qml/Dash/Previews/PreviewSharing.qml:51
232236msgid "Preview Share Item"
233−msgstr ""
237+msgstr "Réamhthaispeántas Rud Le Chéile"
234238
235239#: qml/Dash/PullToRefreshScopeStyle.qml:55
236240msgid "Pull to refresh…"
237−msgstr ""
241+msgstr "Tarraing le hathnuachan..."
238242
239243#: qml/Dash/PullToRefreshScopeStyle.qml:60
240244msgid "Release to refresh…"
241−msgstr ""
245+msgstr "Scaoil le hathnuachan..."
242246
243247#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
244248msgid "Enable location data"
245−msgstr ""
249+msgstr "Ceadaigh logshonraí"
246250
247251#: qml/Dash/ScopesList.qml:67
248252msgid "Manage"
249−msgstr ""
253+msgstr "Bainistigh"
250254
251255#: qml/Dash/ScopesList.qml:113
252256msgid "Home"
@@ -262,111 +266,118 @@ msgstr ""
262266
263267#: qml/Greeter/CoverPage.qml:107
264268msgid "Unlock"
265−msgstr "Díghlasáil"
269+msgstr "Oscail"
266270
267271#: qml/Greeter/LoginList.qml:236
268272msgid "Retry"
269−msgstr ""
273+msgstr "Bain triail as arís"
270274
271275#: qml/Greeter/LoginList.qml:237
272276msgid "Tap to unlock"
273−msgstr ""
277+msgstr "Cnag le hoscail"
274278
275279#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:53
276280msgid "Sorry, incorrect passphrase."
277−msgstr ""
281+msgstr "Pasfhocal míchruinn"
278282
279283#: qml/Greeter/NarrowView.qml:55 qml/Wizard/Pages/passwd-confirm.qml:54
280284msgid "Sorry, incorrect passcode."
281−msgstr ""
285+msgstr "Códfhocal míchruinn"
282286
283287#: qml/Greeter/NarrowView.qml:56
284288msgid "This will be your last attempt."
285−msgstr ""
289+msgstr "Iarracht dheireanach."
286290
287291#: qml/Greeter/NarrowView.qml:58
288292msgid ""
289293"If passphrase is entered incorrectly, your phone will conduct a factory "
290294"reset and all personal data will be deleted."
291295msgstr ""
296+"Más mbíonn pasfhocal mícheart agat arís, déanann do guthan monarchan "
297+"athshocrú agus beidh do shonraí pearsanta scriosadh."
292298
293299#: qml/Greeter/NarrowView.qml:59
294300msgid ""
295301"If passcode is entered incorrectly, your phone will conduct a factory reset "
296302"and all personal data will be deleted."
297303msgstr ""
304+"Más mbíonn paschód mícheart agat arís, déanann do guthan monarchan athshocrú "
305+"agus beidh do shonraí pearsanta scriosadh."
298306
299307#: qml/Greeter/NarrowView.qml:116
300308#, qt-format
301309msgid "Enter %1"
302−msgstr ""
310+msgstr "Cuir isteach %1"
303311
304312#: qml/Greeter/NarrowView.qml:117 qml/Wizard/Pages/passwd-set.qml:60
305313msgid "Enter passphrase"
306−msgstr ""
314+msgstr "Cuir pasfhrása isteach"
307315
308316#: qml/Greeter/NarrowView.qml:118
309317msgid "Enter passcode"
310−msgstr ""
318+msgstr "Cuir paschód isteach"
311319
312320#: qml/Greeter/NarrowView.qml:119
313321#, qt-format
314322msgid "Sorry, incorrect %1"
315−msgstr ""
323+msgstr "Míchruinn, mo léan %1"
316324
317325#: qml/Greeter/NarrowView.qml:120
318326msgid "Sorry, incorrect passphrase"
319−msgstr ""
327+msgstr "Códfhrása míchruinn, mo léan."
320328
321329#: qml/Greeter/NarrowView.qml:121
322330msgctxt "passphrase"
323331msgid "Please re-enter"
324−msgstr ""
332+msgstr "Cuir isteach é arís, le do thoil"
325333
326334#: qml/Greeter/NarrowView.qml:122
327335msgid "Sorry, incorrect passcode"
328−msgstr ""
336+msgstr "Paschód míchruinn, mo léan"
329337
330338#: qml/Notifications/NotificationMenuItemFactory.qml:129
331339msgid "Show password"
332−msgstr ""
340+msgstr "Taispeáin pasfhocal"
333341
334342#: qml/Panel/ActiveCallHint.qml:79
335343msgid "Tap to return to call..."
336−msgstr ""
344+msgstr "Tapáil chun filleadh ar an nglaoch..."
337345
338346#: qml/Panel/ActiveCallHint.qml:92
339347msgid "Conference"
340−msgstr ""
348+msgstr "Glaoch comhdhála"
341349
342350#: qml/Panel/Indicators/MenuItemFactory.qml:731
343351msgid "Nothing is playing"
344−msgstr ""
352+msgstr "Tada á chasadh"
345353
346354#: qml/Panel/Indicators/MenuItemFactory.qml:860
347355#, qt-format
348356msgid "%1 hour"
349357msgid_plural "%1 hours"
350−msgstr[0] ""
351−msgstr[1] ""
358+msgstr[0] "%1 uair"
359+msgstr[1] "%1 uair"
360+msgstr[2] "%1 uair"
352361
353362#: qml/Panel/Indicators/MenuItemFactory.qml:864
354363#, qt-format
355364msgid "%1 minute"
356365msgid_plural "%1 minutes"
357−msgstr[0] ""
358−msgstr[1] ""
366+msgstr[0] "%1 nóiméad"
367+msgstr[1] "%1 nóiméad"
368+msgstr[2] "%1 nóiméad"
359369
360370#: qml/Panel/Indicators/MenuItemFactory.qml:869
361371#, qt-format
362372msgid "%1 second"
363373msgid_plural "%1 seconds"
364−msgstr[0] ""
365−msgstr[1] ""
374+msgstr[0] "%1 soicind"
375+msgstr[1] "%1 soicind"
376+msgstr[2] "%1 soicind"
366377
367378#: qml/Panel/Indicators/MenuItemFactory.qml:872
368379msgid "0 seconds"
369−msgstr ""
380+msgstr "%1 soicind"
370381
371382#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
372383#: qml/Panel/Indicators/MenuItemFactory.qml:874
@@ -376,206 +387,206 @@ msgstr ""
376387
377388#: qml/Panel/Indicators/MenuItemFactory.qml:880
378389msgid "In queue…"
379−msgstr ""
390+msgstr "Ag fanacht a scuaine..."
380391
381392#: qml/Panel/Indicators/MenuItemFactory.qml:884
382393msgid "Downloading"
383−msgstr ""
394+msgstr "Íoslódáil"
384395
385396#: qml/Panel/Indicators/MenuItemFactory.qml:886
386397msgid "Paused, tap to resume"
387−msgstr ""
398+msgstr "Sos, tapáill chun leanúint ar aghaidhdh"
388399
389400#: qml/Panel/Indicators/MenuItemFactory.qml:888
390401msgid "Canceled"
391−msgstr ""
402+msgstr "Curtha Ar Ceal"
392403
393404#: qml/Panel/Indicators/MenuItemFactory.qml:890
394405msgid "Finished"
395−msgstr ""
406+msgstr "Críochnaithe"
396407
397408#: qml/Panel/Indicators/MenuItemFactory.qml:892
398409msgid "Failed, tap to retry"
399−msgstr ""
410+msgstr "Tá teipthe ort, tapáil chun triail eile a bhaint as"
400411
401412#: qml/Panel/Indicators/MessageMenuItemFactory.qml:155
402413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
403414msgctxt "Button: Send a reply message"
404415msgid "Send"
405−msgstr ""
416+msgstr "Seol"
406417
407418#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
408419msgctxt "Label: Hint in message indicator line edit"
409420msgid "Reply"
410−msgstr ""
421+msgstr "Freagra"
411422
412423#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
413424msgctxt "Button: Call back on phone"
414425msgid "Call back"
415−msgstr ""
426+msgstr "Glaoch Ar Ais"
416427
417428#: qml/Panel/Indicators/ModemInfoItem.qml:105
418429msgid "Unlock SIM"
419−msgstr ""
430+msgstr "Díghlasail an SIM"
420431
421432#: qml/Panel/Indicators/RoamingIndication.qml:27
422433msgid "Roaming"
423−msgstr ""
434+msgstr "Fánaíocht"
424435
425436#: qml/Tutorial/TutorialBottom.qml:28
426437msgid "Open special menus"
427−msgstr ""
438+msgstr "Oscail Roghchláir Speisialta"
428439
429440#: qml/Tutorial/TutorialBottom.qml:29
430441msgid "Swipe up from the bottom edge."
431−msgstr ""
442+msgstr "Cuimil anuas ón bhunlíne."
432443
433444#: qml/Tutorial/TutorialBottomFinish.qml:24
434445msgid "This action does different things for different apps"
435−msgstr ""
446+msgstr "Baineann feidhm ar leith leis seo i dtaca le haipeanna éagsúla"
436447
437448#: qml/Tutorial/TutorialBottomFinish.qml:25
438449msgid "Tap here to finish."
439−msgstr ""
450+msgstr "Tapáil anseo chun críochnú."
440451
441452#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
442453#: qml/Tutorial/TutorialRight.qml:144
443454msgid "Tap here to continue."
444−msgstr ""
455+msgstr "Tapáil anseo chun leanúint ar aghaidh."
445456
446457#: qml/Tutorial/TutorialLeft.qml:26
447458msgid "Open the launcher"
448−msgstr ""
459+msgstr "Oscail an lainseálaí"
449460
450461#: qml/Tutorial/TutorialLeft.qml:27
451462msgid "Short swipe from the left edge."
452−msgstr ""
463+msgstr "Cuimil ghearr ón taobh clé."
453464
454465#: qml/Tutorial/TutorialLeftFinish.qml:24
455466msgid "These are the shortcuts to favorite apps"
456−msgstr ""
467+msgstr "Is iad seo na haicearrái i gcomhair na n-aipeanna is fearr leat"
457468
458469#: qml/Tutorial/TutorialPage.qml:178
459470msgid "You almost got it!"
460−msgstr ""
471+msgstr "D'éirigh leat beagnach!"
461472
462473#: qml/Tutorial/TutorialPage.qml:195
463474msgid "Try again."
464−msgstr ""
475+msgstr "Bain triail as arís."
465476
466477#: qml/Tutorial/TutorialRight.qml:31
467478msgid "To view open apps"
468−msgstr ""
479+msgstr "Chun féachaint oscail aipeanna"
469480
470481#: qml/Tutorial/TutorialRight.qml:32
471482msgid "Long swipe from the right edge."
472−msgstr ""
483+msgstr "Cuimil fhada ó taobh clé."
473484
474485#: qml/Tutorial/TutorialRight.qml:122
475486msgid "View all your running tasks."
476−msgstr ""
487+msgstr "Féach ar do thascanna reatha."
477488
478489#: qml/Wizard/Page.qml:89
479490msgctxt "Button: Go back one page in the Wizard"
480491msgid "Back"
481−msgstr ""
492+msgstr "Ar ais"
482493
483494#: qml/Wizard/Pages/10-welcome.qml:27
484495msgid "Hi!"
485−msgstr ""
496+msgstr "Dia duit!"
486497
487498#: qml/Wizard/Pages/10-welcome.qml:44
488499msgid "Welcome to your Ubuntu phone."
489−msgstr ""
500+msgstr "Tá fáilte romhat chuig do fhón Ubuntu."
490501
491502#: qml/Wizard/Pages/10-welcome.qml:52
492503msgid "Let’s get started."
493−msgstr ""
504+msgstr "Tosaímis"
494505
495506#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
496507#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
497508#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
498509#: qml/Wizard/Pages/passwd-set.qml:90
499510msgid "Continue"
500−msgstr ""
511+msgstr "Ar aghaidh leat (go dtí an chéad lch eile)"
501512
502513#: qml/Wizard/Pages/20-sim.qml:25
503514msgid "Add a SIM card and restart your device"
504−msgstr ""
515+msgstr "Cuir cárta SIM isteach agus atosaigh an fearas"
505516
506517#: qml/Wizard/Pages/20-sim.qml:59
507518msgid "Without it, you won’t be able to make calls or use text messaging."
508−msgstr ""
519+msgstr "Gan é, ní bheifeá ábalta glaoch a dhéanamh nó téasc a sheoladh."
509520
510521#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
511522msgid "Skip"
512−msgstr ""
523+msgstr "Scipeáil"
513524
514525#: qml/Wizard/Pages/30-passwd-type.qml:39
515526msgid "Lock security"
516−msgstr ""
527+msgstr "Slándáil ghlasála"
517528
518529#: qml/Wizard/Pages/30-passwd-type.qml:74
519530msgid "Please select how you’d like to unlock your phone."
520−msgstr ""
531+msgstr "Roghnaigh conas ar mhaith leat do fhón a díghlasáil"
521532
522533#: qml/Wizard/Pages/30-passwd-type.qml:97
523534msgctxt "Label: Type of security method"
524535msgid "Swipe"
525−msgstr ""
536+msgstr "Cuimil"
526537
527538#: qml/Wizard/Pages/30-passwd-type.qml:98
528539msgctxt "Label: Description of security method"
529540msgid "No security"
530−msgstr ""
541+msgstr "Gan slándáil"
531542
532543#: qml/Wizard/Pages/30-passwd-type.qml:100
533544msgctxt "Label: Type of security method"
534545msgid "Passcode"
535−msgstr ""
546+msgstr "Paschód"
536547
537548#: qml/Wizard/Pages/30-passwd-type.qml:101
538549msgctxt "Label: Description of security method"
539550msgid "4 digits only"
540−msgstr ""
551+msgstr "Ceithre dhigit amháin"
541552
542553#: qml/Wizard/Pages/30-passwd-type.qml:103
543554msgctxt "Label: Type of security method"
544555msgid "Passphrase"
545−msgstr ""
556+msgstr "Pasfhrása"
546557
547558#: qml/Wizard/Pages/30-passwd-type.qml:104
548559msgctxt "Label: Description of security method"
549560msgid "Numbers and letters"
550−msgstr ""
561+msgstr "Litreacha agus uimhreacha"
551562
552563#: qml/Wizard/Pages/40-wifi.qml:29
553564msgid "Connect to Wi‑Fi"
554−msgstr ""
565+msgstr "Ceangail le Wi-Fi"
555566
556567#: qml/Wizard/Pages/40-wifi.qml:168
557568msgid "Available networks…"
558−msgstr ""
569+msgstr "Gréasáin ar fáil..."
559570
560571#: qml/Wizard/Pages/40-wifi.qml:169
561572msgid "No available networks."
562−msgstr ""
573+msgstr "Níl aon ghréasáin ar fáil."
563574
564575#: qml/Wizard/Pages/50-location.qml:27
565576msgid "Location"
566−msgstr ""
577+msgstr "Suíomh reatha"
567578
568579#: qml/Wizard/Pages/50-location.qml:62
569580msgid "Let the phone detect your location:"
570−msgstr ""
581+msgstr "Lig an fón do shuíomh reatha a aimsiú:"
571582
572583#: qml/Wizard/Pages/50-location.qml:69
573584msgid "Using GPS only (less accurate)"
574−msgstr ""
585+msgstr "Úsáid GPS amháín (easpa cruinnis)"
575586
576587#: qml/Wizard/Pages/50-location.qml:86
577588msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
578−msgstr ""
589+msgstr "Úsáid GPS, gan ainm WIFI agus líonra ceallach eolas (moltar)"
579590
580591#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
581592#: qml/Wizard/Pages/50-location.qml:103
@@ -583,67 +594,73 @@ msgid ""
583594"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
584595"conditions</a>."
585596msgstr ""
597+"Má ghlacann tú leis an rogha seo glacann tú leis na <a href='#'>téarmaí agus "
598+"coinníollacha</a> a bhaineann le Nokia HERE."
586599
587600#: qml/Wizard/Pages/50-location.qml:112
588601msgid "Not at all"
589−msgstr ""
602+msgstr "In aon chor"
590603
591604#: qml/Wizard/Pages/50-location.qml:124
592605msgid "You can change your mind later in <b>System Settings</b>."
593−msgstr ""
606+msgstr "Is féidir do chinneadh a athrú níos déanaí sna <b>Socruithe Córais</b>"
594607
595608#: qml/Wizard/Pages/60-reporting.qml:26
596609msgid "Improving your experience"
597−msgstr ""
610+msgstr "Ag cur le do thaitneamh agus leis an tairbhe"
598611
599612#: qml/Wizard/Pages/60-reporting.qml:46
600613msgid ""
601614"Your phone is set up to automatically report errors to Canonical and its "
602615"partners, the makers of the operating system."
603616msgstr ""
617+"Cuireann do fhón earráidí in iúl go huathoibríoch do Chanonical agus a "
618+"chomhpháirithe, lucht déanta an chórais oibre."
604619
605620#: qml/Wizard/Pages/60-reporting.qml:53
606621msgid ""
607622"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
608623"Privacy</b>"
609624msgstr ""
625+"Is féidir é seo a mhúchadh sna Socruithe Córais faoi Shlándáil agus "
626+"Príobháideachas"
610627
611628#: qml/Wizard/Pages/80-finished.qml:24
612629msgid "All done"
613−msgstr ""
630+msgstr "Déanta"
614631
615632#: qml/Wizard/Pages/80-finished.qml:39
616633msgid "Nice work!"
617−msgstr ""
634+msgstr "D'éirigh leat!"
618635
619636#: qml/Wizard/Pages/80-finished.qml:46
620637msgid "Your phone is now ready to use."
621−msgstr ""
638+msgstr "Tá do fhón reidh le húsáid anois."
622639
623640#: qml/Wizard/Pages/80-finished.qml:53
624641msgid "Finish"
625−msgstr ""
642+msgstr "Críoch"
626643
627644#: qml/Wizard/Pages/here-terms.qml:27
628645msgid "Terms & Conditions"
629−msgstr ""
646+msgstr "Téarmaí agus Coinníollacha"
630647
631648#: qml/Wizard/Pages/passwd-confirm.qml:49
632649msgid "Confirm passphrase"
633−msgstr ""
650+msgstr "Deimhnigh pasfhrása"
634651
635652#: qml/Wizard/Pages/passwd-confirm.qml:50
636653msgid "Confirm passcode"
637−msgstr ""
654+msgstr "Deimhnigh paschód"
638655
639656#: qml/Wizard/Pages/passwd-confirm.qml:53
640657#: qml/Wizard/Pages/passwd-confirm.qml:54
641658msgid "Please try again."
642−msgstr ""
659+msgstr "Bain trial as arís."
643660
644661#: qml/Wizard/Pages/passwd-set.qml:61
645662msgid "Choose your passcode"
646−msgstr ""
663+msgstr "Roghnaigh do phaschód"
647664
648665#: qml/Wizard/Pages/passwd-set.qml:68
649666msgid "Passphrase must be 4 characters long"
po/gd.po+36−15
@@ -6,19 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-16 10:56+0000\n"
1212"Last-Translator: GunChleoc <Unknown>\n"
1313"Language-Team: Fòram na Gàidhlig\n"
14+"Language: gd\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
1819"(n > 2 && n < 20) ? 2 : 3;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
21−"Language: gd\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2222
2323#: plugins/IntegratedLightDM/Greeter.cpp:112
2424msgid "Password: "
@@ -159,27 +159,29 @@ msgstr "Ceart ma-thà"
159159
160160#: qml/Components/ModeSwitchWarningDialog.qml:32
161161msgid "Apps may have unsaved data:"
162−msgstr ""
162+msgstr "Aplacaidean aig a bheil dàta gun sàbhaladh ma dh'fhaoidte:"
163163
164164#: qml/Components/ModeSwitchWarningDialog.qml:57
165165msgid "Re-dock, save your work and close these apps to continue."
166166msgstr ""
167+"Ath-dhocaich, sàbhail d' obair is dùin na h-aplacaidean sin gus leantainn "
168+"air adhart."
167169
168170#: qml/Components/ModeSwitchWarningDialog.qml:63
169171msgid "Or force close now (unsaved data will be lost)."
170−msgstr ""
172+msgstr "No sparr fàgail air an-dràsta (thèid dàta gun sàbhaladh air chall)."
171173
172174#: qml/Components/ModeSwitchWarningDialog.qml:75
173175msgid "OK, I will reconnect"
174−msgstr ""
176+msgstr "Ceart ma-thà, ceanglaidh mi a-rithist"
175177
176178#: qml/Components/ModeSwitchWarningDialog.qml:76
177179msgid "Reconnect now!"
178−msgstr ""
180+msgstr "Ath-cheangail an-dràsta!"
179181
180182#: qml/Components/ModeSwitchWarningDialog.qml:88
181183msgid "Close all"
182−msgstr ""
184+msgstr "Dùin na h-uile"
183185
184186#: qml/Dash/DashPageHeader.qml:265
185187msgctxt "Button: Open the Ubuntu Store"
@@ -424,7 +426,7 @@ msgstr "Dh'fhàillig leis, thoir gnogag gus feuchainn a-rithist"
424426#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
425427msgctxt "Button: Send a reply message"
426428msgid "Send"
427−msgstr ""
429+msgstr "Cuir"
428430
429431#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
430432msgctxt "Label: Hint in message indicator line edit"
@@ -434,7 +436,7 @@ msgstr "Freagairt"
434436#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
435437msgctxt "Button: Call back on phone"
436438msgid "Call back"
437−msgstr ""
439+msgstr "Fònaig air ais"
438440
439441#: qml/Panel/Indicators/ModemInfoItem.qml:105
440442msgid "Unlock SIM"
@@ -694,13 +696,31 @@ msgstr "〈 %1"
694696msgid "%1 〉"
695697msgstr "%1 〉"
696698
699+#~ msgid ""
700+#~ "Your device is now connected to an external display. Use this screen as a "
701+#~ "touch pad to interact with the mouse."
702+#~ msgstr ""
703+#~ "Tha an t-uidheam agad air a cheangal ri uidheam-taisbeanaidh air an taobh "
704+#~ "a-muigh a-nis. Cleachd an sgrìn seo 'na phada-suathaidh gus gnìomh "
705+#~ "luchaige a dhèanamh."
706+
707+#~ msgid "Welcome to your Ubuntu device."
708+#~ msgstr "Fàilte dhan uidheam Ubuntu agad."
709+
710+#~ msgid "Please select how you’d like to unlock your device."
711+#~ msgstr ""
712+#~ "Tagh an dòigh sa tha thu airson a' ghlas a thoirt far an uidheam agad."
713+
714+#~ msgid "Your device is now ready to use."
715+#~ msgstr "Tha an t-uidheam agad ullamh a-nis."
716+
697717#~ msgid "Skip intro"
698718#~ msgstr "Gearr leum thairis air an ro-ràdh"
699719
700720#~ msgid "Try swiping from the right edge to unlock the phone"
701721#~ msgstr ""
702−#~ "Feuch is dèan grad-shlaighdeadh a-steach on oir dheas gus a' ghlas a thoirt "
703−#~ "far an fhòn"
722+#~ "Feuch is dèan grad-shlaighdeadh a-steach on oir dheas gus a' ghlas a "
723+#~ "thoirt far an fhòn"
704724
705725#~ msgid "Right edge"
706726#~ msgstr "An oir dheas"
@@ -752,8 +772,9 @@ msgstr "%1 〉"
752772#~ "You have now mastered the edge gestures and can start using the "
753773#~ "phone<br><br>Tap on the screen to start"
754774#~ msgstr ""
755−#~ "Fhuair thu air na gluasadan oire ceart a dhèanamh a-nis agus is urrainn dhut "
756−#~ "am fòn a chleachdadh<br><br>Thoir gnogag air an sgrìn airson tòiseachadh"
775+#~ "Fhuair thu air na gluasadan oire ceart a dhèanamh a-nis agus is urrainn "
776+#~ "dhut am fòn a chleachdadh<br><br>Thoir gnogag air an sgrìn airson "
777+#~ "tòiseachadh"
757778
758779#~ msgid "All"
759780#~ msgstr "Na h-uile"
po/gl.po+24−6
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-12-04 17:06+0000\n"
11+"PO-Revision-Date: 2016-01-15 14:56+0000\n"
1212"Last-Translator: Marcos Lans <Unknown>\n"
1313"Language-Team: Galician <gl@li.org>\n"
14+"Language: gl\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -154,6 +155,8 @@ msgstr "Aplicativos que poden ter datos sen gardar:"
154155#: qml/Components/ModeSwitchWarningDialog.qml:57
155156msgid "Re-dock, save your work and close these apps to continue."
156157msgstr ""
158+"Para continuar conecte de novo o dispositivo, garde o traballo e peche estes "
159+"aplicativos."
157160
158161#: qml/Components/ModeSwitchWarningDialog.qml:63
159162msgid "Or force close now (unsaved data will be lost)."
@@ -509,8 +512,7 @@ msgstr "Engada unha tarxeta SIM e reinicie o dispositivo"
509512
510513#: qml/Wizard/Pages/20-sim.qml:59
511514msgid "Without it, you won’t be able to make calls or use text messaging."
512−msgstr ""
513−"Sen ela, non poderá realizar chamadas nin usar a mensaxería de texto."
515+msgstr "Sen ela, non poderá realizar chamadas nin usar a mensaxería de texto."
514516
515517#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
516518msgid "Skip"
@@ -672,6 +674,22 @@ msgstr "〈 %1"
672674msgid "%1 〉"
673675msgstr "%1 〉"
674676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "O dispositivo está agora conectado a unha pantalla externa. Use esta "
682+#~ "pantalla como área táctil para interactuar co rato."
683+
684+#~ msgid "Welcome to your Ubuntu device."
685+#~ msgstr "Benvido/a ao seu dispositivo Ubuntu."
686+
687+#~ msgid "Please select how you’d like to unlock your device."
688+#~ msgstr "Seleccione o xeito de desbloquear o dispositivo."
689+
690+#~ msgid "Your device is now ready to use."
691+#~ msgstr "O dispositivo xa está listo para o seu uso."
692+
675693#~ msgid "Confirm"
676694#~ msgstr "Confirmar"
677695
po/gv.po+9−7
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-04-02 14:24+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Manx <gv@li.org>\n"
14+"Language: gv\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : (n == 2 ? 1 : 2);\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -691,8 +692,8 @@ msgstr ""
691692
692693#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
693694#~ msgstr ""
694−#~ "Flip woish yn çheu hoshtal dy soilshaghey yn lunneyder son raad aashagh dys "
695−#~ "ny h-appyn"
695+#~ "Flip woish yn çheu hoshtal dy soilshaghey yn lunneyder son raad aashagh "
696+#~ "dys ny h-appyn"
696697
697698#~ msgid "Well done"
698699#~ msgstr "Jeant dy mie"
@@ -722,8 +723,9 @@ msgstr ""
722723#~ "You have now mastered the edge gestures and can start using the "
723724#~ "phone<br><br>Tap on the screen to start"
724725#~ msgstr ""
725−#~ "T'ou nish oayllagh er ny cowraghyn oirr as foddee oo cur toshiaght er jannoo "
726−#~ "ymmyd jeh'n çhellvane<br><br>Jean broddey yn scaailan dy ghoaill toshiaght"
726+#~ "T'ou nish oayllagh er ny cowraghyn oirr as foddee oo cur toshiaght er "
727+#~ "jannoo ymmyd jeh'n çhellvane<br><br>Jean broddey yn scaailan dy ghoaill "
728+#~ "toshiaght"
727729
728730#~ msgid "Store"
729731#~ msgstr "Shapp"
po/he.po+6−5
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-12 08:47+0000\n"
1212"Last-Translator: Yaron <sh.yaron@gmail.com>\n"
1313"Language-Team: Hebrew <he@li.org>\n"
14+"Language: he\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -713,8 +714,8 @@ msgstr ""
713714#~ "You have now mastered the edge gestures and can start using the "
714715#~ "phone<br><br>Tap on the screen to start"
715716#~ msgstr ""
716−#~ "ברגעים אלו סיימת את התמחותך בשימוש במחוות קצה והטלפון פתוח לשימושך<br><br>נא "
717−#~ "לגעת במסך כדי להתחיל"
717+#~ "ברגעים אלו סיימת את התמחותך בשימוש במחוות קצה והטלפון פתוח "
718+#~ "לשימושך<br><br>נא לגעת במסך כדי להתחיל"
718719
719720#~ msgid "Power off"
720721#~ msgstr "כיבוי"
po/hi.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-01-15 01:49+0000\n"
1212"Last-Translator: Siddhanathan Shanmugam <Unknown>\n"
1313"Language-Team: Hindi <hi@li.org>\n"
14+"Language: hi\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/hr.po+25−7
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-06-27 04:14+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Croatian <hr@li.org>\n"
14+"Language: hr\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
18+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -158,6 +159,7 @@ msgstr "Aplikacija možda ima nespremljene podatke:"
158159#: qml/Components/ModeSwitchWarningDialog.qml:57
159160msgid "Re-dock, save your work and close these apps to continue."
160161msgstr ""
162+"Za nastavak ponovno povežite, spremite svoj rad i zatvorite te aplikacije."
161163
162164#: qml/Components/ModeSwitchWarningDialog.qml:63
163165msgid "Or force close now (unsaved data will be lost)."
@@ -595,8 +597,8 @@ msgid ""
595597"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
596598"conditions</a>."
597599msgstr ""
598−"Odabirom ove mogućnosti prihvaćate Nokia HERE <a href='#'>uvjete i "
599−"odredbe</a>."
600+"Odabirom ove mogućnosti prihvaćate Nokia HERE <a href='#'>uvjete i odredbe</"
601+"a>."
600602
601603#: qml/Wizard/Pages/50-location.qml:112
602604msgid "Not at all"
@@ -679,6 +681,22 @@ msgstr "〈 %1"
679681msgid "%1 〉"
680682msgstr "%1 〉"
681683
684+#~ msgid ""
685+#~ "Your device is now connected to an external display. Use this screen as a "
686+#~ "touch pad to interact with the mouse."
687+#~ msgstr ""
688+#~ "Vaš uređaj je sada povezan s vanjskim zaslonom. Koristite ovaj uređaj kao "
689+#~ "touchpad za interakciju s mišem."
690+
691+#~ msgid "Welcome to your Ubuntu device."
692+#~ msgstr "Dobrodošli u svoj Ubuntu uređaj."
693+
694+#~ msgid "Please select how you’d like to unlock your device."
695+#~ msgstr "Odaberite kako želite otključavati svoj uređaj."
696+
697+#~ msgid "Your device is now ready to use."
698+#~ msgstr "Vaš uređaj je sada spreman za upotrebu."
699+
682700#~ msgid "Confirm"
683701#~ msgstr "Potvrdi"
684702
po/hu.po+23−6
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-12-30 09:49+0000\n"
11+"PO-Revision-Date: 2016-02-16 07:23+0000\n"
1212"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
1313"Language-Team: Hungarian <hu@li.org>\n"
14+"Language: hu\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-31 05:35+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -677,6 +678,22 @@ msgstr "〈 %1"
677678msgid "%1 〉"
678679msgstr "%1 〉"
679680
681+#~ msgid ""
682+#~ "Your device is now connected to an external display. Use this screen as a "
683+#~ "touch pad to interact with the mouse."
684+#~ msgstr ""
685+#~ "Egy külső kijelzőhöz csatlakoztatta a készülékét. A telefon kijelzőjén "
686+#~ "tett ujjmozdulatokkal mozgathatja az egeret."
687+
688+#~ msgid "Welcome to your Ubuntu device."
689+#~ msgstr "Köszönti az Ubuntus eszköze."
690+
691+#~ msgid "Please select how you’d like to unlock your device."
692+#~ msgstr "Válassza ki, hogy milyen módon szeretné feloldani az eszközét."
693+
694+#~ msgid "Your device is now ready to use."
695+#~ msgstr "Az eszköze készen áll a használatra."
696+
680697#~ msgid "Confirm"
681698#~ msgstr "Megerősítés"
682699
@@ -728,8 +745,8 @@ msgstr "%1 〉"
728745#~ "You have now mastered the edge gestures and can start using the "
729746#~ "phone<br><br>Tap on the screen to start"
730747#~ msgstr ""
731−#~ "Elsajátította a gesztusokat, és megkezdheti a telefon "
732−#~ "használatát.<br><br>Koppintson a képernyőre a kezdéshez."
748+#~ "Elsajátította a gesztusokat, és megkezdheti a telefon használatát."
749+#~ "<br><br>Koppintson a képernyőre a kezdéshez."
733750
734751#~ msgid "Try swiping from the top edge to access the indicators"
735752#~ msgstr "Az állapotmenük eléréséhez csúsztassa ujját a felső szélről"
po/hy.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-10-28 06:34+0000\n"
1212"Last-Translator: Vahan Harutyunyan <Unknown>\n"
1313"Language-Team: Armenian <hy@li.org>\n"
14+"Language: hy\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/ia.po+16−15
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-08-25 19:31+0000\n"
1212"Last-Translator: karm <melo@carmu.com>\n"
1313"Language-Team: Interlingua <ia@li.org>\n"
14+"Language: ia\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -29,7 +30,7 @@ msgstr "Via-breve a pin"
2930
3031#: plugins/Unity/Launcher/launcheritem.cpp:52
3132msgid "Quit"
32−msgstr ""
33+msgstr "Quitar"
3334
3435#: plugins/Unity/Launcher/launcheritem.cpp:106
3536msgid "Unpin shortcut"
@@ -153,27 +154,27 @@ msgstr "OK"
153154
154155#: qml/Components/ModeSwitchWarningDialog.qml:32
155156msgid "Apps may have unsaved data:"
156−msgstr ""
157+msgstr "Le applicationes pote haber datos non salvate:"
157158
158159#: qml/Components/ModeSwitchWarningDialog.qml:57
159160msgid "Re-dock, save your work and close these apps to continue."
160−msgstr ""
161+msgstr "Re-connecte, salva tu labor e claude iste applicationes pro continuar."
161162
162163#: qml/Components/ModeSwitchWarningDialog.qml:63
163164msgid "Or force close now (unsaved data will be lost)."
164−msgstr ""
165+msgstr "O fortia clauder nunc (le datos non salveguardate essera perdite)."
165166
166167#: qml/Components/ModeSwitchWarningDialog.qml:75
167168msgid "OK, I will reconnect"
168−msgstr ""
169+msgstr "OK, io va reconnecter"
169170
170171#: qml/Components/ModeSwitchWarningDialog.qml:76
171172msgid "Reconnect now!"
172−msgstr ""
173+msgstr "Reconnecter nunc!"
173174
174175#: qml/Components/ModeSwitchWarningDialog.qml:88
175176msgid "Close all"
176−msgstr ""
177+msgstr "Clauder toto"
177178
178179#: qml/Dash/DashPageHeader.qml:265
179180msgctxt "Button: Open the Ubuntu Store"
@@ -234,7 +235,7 @@ msgstr "Adder un revision"
234235
235236#: qml/Dash/Previews/PreviewSharing.qml:51
236237msgid "Preview Share Item"
237−msgstr ""
238+msgstr "Elemento compartite de vista preliminar"
238239
239240#: qml/Dash/PullToRefreshScopeStyle.qml:55
240241msgid "Pull to refresh…"
@@ -410,7 +411,7 @@ msgstr "Fallite, colpar pro re-provar"
410411#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
411412msgctxt "Button: Send a reply message"
412413msgid "Send"
413−msgstr ""
414+msgstr "Inviar"
414415
415416#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
416417msgctxt "Label: Hint in message indicator line edit"
@@ -420,7 +421,7 @@ msgstr "Responde"
420421#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
421422msgctxt "Button: Call back on phone"
422423msgid "Call back"
423−msgstr ""
424+msgstr "Appellar retro"
424425
425426#: qml/Panel/Indicators/ModemInfoItem.qml:105
426427msgid "Unlock SIM"
@@ -604,8 +605,8 @@ msgstr "No, del toto"
604605#: qml/Wizard/Pages/50-location.qml:124
605606msgid "You can change your mind later in <b>System Settings</b>."
606607msgstr ""
607−"Tu pote cambiar tu desiderata plus tarde in <b>Configurationes del "
608−"systema</b>."
608+"Tu pote cambiar tu desiderata plus tarde in <b>Configurationes del systema</"
609+"b>."
609610
610611#: qml/Wizard/Pages/60-reporting.qml:26
611612msgid "Improving your experience"
po/id.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-06-26 22:35+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Indonesian <id@li.org>\n"
14+"Language: id\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/is.po+8−7
@@ -8,18 +8,18 @@
88msgid ""
99msgstr ""
1010"Project-Id-Version: po_unity8-is\n"
11−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
11+"Report-Msgid-Bugs-To: \n"
1212"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1313"PO-Revision-Date: 2014-11-13 09:32+0000\n"
1414"Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n"
1515"Language-Team: Icelandic <translation-team-is@lists.sourceforge.net>\n"
16+"Language: is\n"
1617"MIME-Version: 1.0\n"
1718"Content-Type: text/plain; charset=UTF-8\n"
1819"Content-Transfer-Encoding: 8bit\n"
1920"Plural-Forms: nplurals=2; plural=n != 1;\n"
20−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
21−"X-Generator: Launchpad (build 17865)\n"
22−"Language: is\n"
21+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
22+"X-Generator: Launchpad (build 17925)\n"
2323
2424#: plugins/IntegratedLightDM/Greeter.cpp:112
2525msgid "Password: "
@@ -703,7 +703,8 @@ msgstr ""
703703
704704#~ msgid "Try swiping from the right edge to unlock the phone"
705705#~ msgstr ""
706−#~ "Prófaðu að strjúka fingrinum frá hægri brúninni til að aflæsa símanum þínum."
706+#~ "Prófaðu að strjúka fingrinum frá hægri brúninni til að aflæsa símanum "
707+#~ "þínum."
707708
708709#~ msgid "Try swiping from the top edge to access the indicators"
709710#~ msgstr "Reyndu að strjúka frá toppi til að fá aðgang að tilkynningum"
@@ -718,8 +719,8 @@ msgstr ""
718719#~ "You have now mastered the edge gestures and can start using the "
719720#~ "phone<br><br>Tap on the screen to start"
720721#~ msgstr ""
721−#~ "Þú ert núna með æfingu í að nota skjáhreyfingar og getur því farið að nota "
722−#~ "símann<br><br>Sláðu létt á skjáinn til að byrja"
722+#~ "Þú ert núna með æfingu í að nota skjáhreyfingar og getur því farið að "
723+#~ "nota símann<br><br>Sláðu létt á skjáinn til að byrja"
723724
724725#~ msgid "Type or say a command"
725726#~ msgstr "Skrifaðu eða segðu skipun"
po/it.po+14−11
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-09-18 08:24+0000\n"
1212"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
1313"Language-Team: Italian <it@li.org>\n"
14+"Language: it\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -155,27 +156,29 @@ msgstr "OK"
155156
156157#: qml/Components/ModeSwitchWarningDialog.qml:32
157158msgid "Apps may have unsaved data:"
158−msgstr ""
159+msgstr "Le app potrebbero contenere dati non salvati:"
159160
160161#: qml/Components/ModeSwitchWarningDialog.qml:57
161162msgid "Re-dock, save your work and close these apps to continue."
162163msgstr ""
164+"Collegare nuovamente il dispositivo, salvare il lavoro e chiudere queste app "
165+"per continuare."
163166
164167#: qml/Components/ModeSwitchWarningDialog.qml:63
165168msgid "Or force close now (unsaved data will be lost)."
166−msgstr ""
169+msgstr "Oppure forzare la chiusura ora (i dati non salvati verranno persi)."
167170
168171#: qml/Components/ModeSwitchWarningDialog.qml:75
169172msgid "OK, I will reconnect"
170−msgstr ""
173+msgstr "Ok, collegherò il dispositivo"
171174
172175#: qml/Components/ModeSwitchWarningDialog.qml:76
173176msgid "Reconnect now!"
174−msgstr ""
177+msgstr "Collegare ora."
175178
176179#: qml/Components/ModeSwitchWarningDialog.qml:88
177180msgid "Close all"
178−msgstr ""
181+msgstr "Chiudi tutto"
179182
180183#: qml/Dash/DashPageHeader.qml:265
181184msgctxt "Button: Open the Ubuntu Store"
@@ -236,7 +239,7 @@ msgstr "Aggiungi una recensione"
236239
237240#: qml/Dash/Previews/PreviewSharing.qml:51
238241msgid "Preview Share Item"
239−msgstr ""
242+msgstr "Anteprima elementi da condividere"
240243
241244#: qml/Dash/PullToRefreshScopeStyle.qml:55
242245msgid "Pull to refresh…"
@@ -412,7 +415,7 @@ msgstr "Non riuscito. Tocca per riprovare"
412415#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
413416msgctxt "Button: Send a reply message"
414417msgid "Send"
415−msgstr ""
418+msgstr "Invia"
416419
417420#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
418421msgctxt "Label: Hint in message indicator line edit"
@@ -422,7 +425,7 @@ msgstr "Rispondi"
422425#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
423426msgctxt "Button: Call back on phone"
424427msgid "Call back"
425−msgstr ""
428+msgstr "Richiama"
426429
427430#: qml/Panel/Indicators/ModemInfoItem.qml:105
428431msgid "Unlock SIM"
po/ja.po+23−15
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-10-05 10:05+0000\n"
1212"Last-Translator: Kentaro Kazuhama <Unknown>\n"
1313"Language-Team: Japanese <ja@li.org>\n"
14+"Language: ja\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -29,7 +30,7 @@ msgstr "ショートカットを追加する"
2930
3031#: plugins/Unity/Launcher/launcheritem.cpp:52
3132msgid "Quit"
32−msgstr ""
33+msgstr "終了"
3334
3435#: plugins/Unity/Launcher/launcheritem.cpp:106
3536msgid "Unpin shortcut"
@@ -56,7 +57,7 @@ msgstr[0] "%1 分待ってからやり直してください…"
5657#: qml/Components/Dialogs.qml:144
5758msgctxt "Title: Lock/Log out dialog"
5859msgid "Log out"
59−msgstr ""
60+msgstr "ログアウト"
6061
6162#: qml/Components/Dialogs.qml:145
6263msgid "Are you sure you want to log out?"
@@ -65,12 +66,12 @@ msgstr "本当にログアウトしますか?"
6566#: qml/Components/Dialogs.qml:147
6667msgctxt "Button: Lock the system"
6768msgid "Lock"
68−msgstr ""
69+msgstr "ロック"
6970
7071#: qml/Components/Dialogs.qml:154
7172msgctxt "Button: Log out from the system"
7273msgid "Log Out"
73−msgstr ""
74+msgstr "ログアウト"
7475
7576#: qml/Components/Dialogs.qml:161 qml/Components/Dialogs.qml:194
7677#: qml/Components/Dialogs.qml:253
@@ -80,7 +81,7 @@ msgstr "キャンセル"
8081#: qml/Components/Dialogs.qml:173
8182msgctxt "Title: Reboot/Shut down dialog"
8283msgid "Shut down"
83−msgstr ""
84+msgstr "シャットダウン"
8485
8586#: qml/Components/Dialogs.qml:174
8687msgid "Are you sure you want to shut down?"
@@ -89,17 +90,17 @@ msgstr "本当にシャットダウンしますか?"
8990#: qml/Components/Dialogs.qml:176
9091msgctxt "Button: Reboot the system"
9192msgid "Reboot"
92−msgstr ""
93+msgstr "再起動"
9394
9495#: qml/Components/Dialogs.qml:185
9596msgctxt "Button: Shut down the system"
9697msgid "Shut down"
97−msgstr ""
98+msgstr "シャットダウン"
9899
99100#: qml/Components/Dialogs.qml:207
100101msgctxt "Title: Reboot dialog"
101102msgid "Reboot"
102−msgstr ""
103+msgstr "再起動"
103104
104105#: qml/Components/Dialogs.qml:208
105106msgid "Are you sure you want to reboot?"
@@ -287,13 +288,17 @@ msgstr "これが最後のチャンスです。"
287288msgid ""
288289"If passphrase is entered incorrectly, your phone will conduct a factory "
289290"reset and all personal data will be deleted."
290−msgstr "パスフレーズが間違っている場合、ファクトリーリセットを実施し、すべての個人データは削除されます。"
291+msgstr ""
292+"パスフレーズが間違っている場合、ファクトリーリセットを実施し、すべての個人"
293+"データは削除されます。"
291294
292295#: qml/Greeter/NarrowView.qml:59
293296msgid ""
294297"If passcode is entered incorrectly, your phone will conduct a factory reset "
295298"and all personal data will be deleted."
296−msgstr "パスコードが間違っている場合、ファクトリーリセットを実施し、すべての個人データは削除されます。"
299+msgstr ""
300+"パスコードが間違っている場合、ファクトリーリセットを実施し、すべての個人デー"
301+"タは削除されます。"
297302
298303#: qml/Greeter/NarrowView.qml:116
299304#, qt-format
@@ -673,7 +678,9 @@ msgstr ""
673678#~ msgstr "左端"
674679
675680#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
676−#~ msgstr "アプリに素早くアクセスできるLauncherを表示するには左からスワイプしてください"
681+#~ msgstr ""
682+#~ "アプリに素早くアクセスできるLauncherを表示するには左からスワイプしてくださ"
683+#~ "い"
677684
678685#~ msgid "Swipe up again to close the settings screen"
679686#~ msgstr "設定画面を閉じるにはもう一度上にスワイプしてください"
@@ -709,7 +716,8 @@ msgstr ""
709716#~ "You have now mastered the edge gestures and can start using the "
710717#~ "phone<br><br>Tap on the screen to start"
711718#~ msgstr ""
712−#~ "これでスマートフォンの操作に必要な、画面端を用いたジェスチャーを習得できました。<br><br>利用を開始するなら画面をタップしてください"
719+#~ "これでスマートフォンの操作に必要な、画面端を用いたジェスチャーを習得できま"
720+#~ "した。<br><br>利用を開始するなら画面をタップしてください"
713721
714722#~ msgid "Power off"
715723#~ msgstr "電源を切る"
po/km.po+10−14
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-08-20 02:48+0000\n"
1212"Last-Translator: Sophea Sok <sksophea@gmail.com>\n"
1313"Language-Team: Khmer <km@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -291,18 +292,16 @@ msgid ""
291292"If passphrase is entered incorrectly, your phone will conduct a factory "
292293"reset and all personal data will be deleted."
293294msgstr ""
294−"បើ​បញ្ចូល​ឃ្លា​សម្ងាត់​មិន​ត្រឹមត្រូវ "
295−"ទូរស័ព្ទ​របស់​អ្នក​នឹង​កំណត់​ទៅ​ទិន្នន័យ​ពី​រោងចក្រ​វិញ "
296−"ហើយ​ទិន្នន័យ​ផ្ទាល់ខ្លួន​ទាំងអស់​របស់​អ្នក​នឹង​ត្រូវ​បាន​លុប។"
295+"បើ​បញ្ចូល​ឃ្លា​សម្ងាត់​មិន​ត្រឹមត្រូវ ទូរស័ព្ទ​របស់​អ្នក​នឹង​កំណត់​ទៅ​ទិន្នន័យ​ពី​រោងចក្រ​វិញ ហើយ​ទិន្នន័យ​ផ្ទាល់ខ្លួន​ទាំងអស់​"
296+"របស់​អ្នក​នឹង​ត្រូវ​បាន​លុប។"
297297
298298#: qml/Greeter/NarrowView.qml:59
299299msgid ""
300300"If passcode is entered incorrectly, your phone will conduct a factory reset "
301301"and all personal data will be deleted."
302302msgstr ""
303−"បើ​បញ្ចូល​កូដ​សម្ងាត់​មិន​ត្រឹមត្រូវ "
304−"ទូរស័ព្ទ​របស់​អ្នក​នឹង​កំណត់​ទៅ​ទិន្នន័យ​ពី​រោងចក្រ​វិញ "
305−"ហើយ​ទិន្នន័យ​ផ្ទាល់ខ្លួន​ទាំងអស់​របស់​អ្នក​នឹង​ត្រូវ​បាន​លុប។"
303+"បើ​បញ្ចូល​កូដ​សម្ងាត់​មិន​ត្រឹមត្រូវ ទូរស័ព្ទ​របស់​អ្នក​នឹង​កំណត់​ទៅ​ទិន្នន័យ​ពី​រោងចក្រ​វិញ ហើយ​ទិន្នន័យ​ផ្ទាល់ខ្លួន​ទាំងអស់​"
304+"របស់​អ្នក​នឹង​ត្រូវ​បាន​លុប។"
306305
307306#: qml/Greeter/NarrowView.qml:116
308307#, qt-format
@@ -694,9 +693,7 @@ msgstr "%1 〉"
694693#~ msgstr "គែមឆ្វេង"
695694
696695#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
697−#~ msgstr ""
698−#~ "អូស​ពី​គែម​ឆ្វេង "
699−#~ "ដើម្បី​បង្ហាញ​កម្មវិធី​ចាប់ផ្ដើម​សម្រាប់​ចូល​ដំណើរ​ការ​កម្មវិធី​រហ័ស"
696+#~ msgstr "អូស​ពី​គែម​ឆ្វេង ដើម្បី​បង្ហាញ​កម្មវិធី​ចាប់ផ្ដើម​សម្រាប់​ចូល​ដំណើរ​ការ​កម្មវិធី​រហ័ស"
700697
701698#~ msgid "Well done"
702699#~ msgstr "ធ្វើ​បាន​ល្អ"
@@ -723,8 +720,7 @@ msgstr "%1 〉"
723720#~ "You have now mastered the edge gestures and can start using the "
724721#~ "phone<br><br>Tap on the screen to start"
725722#~ msgstr ""
726−#~ "ឥឡូវ​អ្នក​បាន​ពិនិត្យ​កាយវិការ​គែម​ "
727−#~ "និង​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរស័ព្ទ<br><br>ប៉ះ លើ​អេក្រង់​ដើម្បី​ចាប់ផ្ដើម"
723+#~ "ឥឡូវ​អ្នក​បាន​ពិនិត្យ​កាយវិការ​គែម​ និង​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរស័ព្ទ<br><br>ប៉ះ លើ​អេក្រង់​ដើម្បី​ចាប់ផ្ដើម"
728724
729725#~ msgid "All"
730726#~ msgstr "ទាំងអស់"
po/kn.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-06-27 05:43+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kannada <kn@li.org>\n"
14+"Language: kn\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/ko.po+36−18
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-08-19 13:02+0000\n"
1212"Last-Translator: MinSik CHO <Unknown>\n"
1313"Language-Team: Korean <ko@li.org>\n"
14+"Language: ko\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -148,27 +149,27 @@ msgstr "확인"
148149
149150#: qml/Components/ModeSwitchWarningDialog.qml:32
150151msgid "Apps may have unsaved data:"
151−msgstr ""
152+msgstr "프로그램에 저장하지 않은 데이터가 있을 때:"
152153
153154#: qml/Components/ModeSwitchWarningDialog.qml:57
154155msgid "Re-dock, save your work and close these apps to continue."
155−msgstr ""
156+msgstr "다시 도킹해 작업을 저장하고 프로그램을 닫은 후 계속합니다."
156157
157158#: qml/Components/ModeSwitchWarningDialog.qml:63
158159msgid "Or force close now (unsaved data will be lost)."
159−msgstr ""
160+msgstr "강제로 지금 끝냅니다.(저장하지 않은 데이터를 잃게 됩니다.)"
160161
161162#: qml/Components/ModeSwitchWarningDialog.qml:75
162163msgid "OK, I will reconnect"
163−msgstr ""
164+msgstr "다시 접속합니다."
164165
165166#: qml/Components/ModeSwitchWarningDialog.qml:76
166167msgid "Reconnect now!"
167−msgstr ""
168+msgstr "지급 다시 접속!"
168169
169170#: qml/Components/ModeSwitchWarningDialog.qml:88
170171msgid "Close all"
171−msgstr ""
172+msgstr "모두 닫기"
172173
173174#: qml/Dash/DashPageHeader.qml:265
174175msgctxt "Button: Open the Ubuntu Store"
@@ -229,7 +230,7 @@ msgstr "평가 추가"
229230
230231#: qml/Dash/Previews/PreviewSharing.qml:51
231232msgid "Preview Share Item"
232−msgstr ""
233+msgstr "공유 항목 미리 보기"
233234
234235#: qml/Dash/PullToRefreshScopeStyle.qml:55
235236msgid "Pull to refresh…"
@@ -287,13 +288,17 @@ msgstr "마지막 시도입니다."
287288msgid ""
288289"If passphrase is entered incorrectly, your phone will conduct a factory "
289290"reset and all personal data will be deleted."
290−msgstr "이번에도 올바르지 않은 암호문을 입력하면 휴대 전화를 공장 초기화하여 모든 개인 정보를 삭제합니다."
291+msgstr ""
292+"이번에도 올바르지 않은 암호문을 입력하면 휴대 전화를 공장 초기화하여 모든 개"
293+"인 정보를 삭제합니다."
291294
292295#: qml/Greeter/NarrowView.qml:59
293296msgid ""
294297"If passcode is entered incorrectly, your phone will conduct a factory reset "
295298"and all personal data will be deleted."
296−msgstr "이번에도 올바르지 않은 패스코드를 입력하면 휴대 전화를 공장 초기화하여 모든 개인 정보를 삭제합니다."
299+msgstr ""
300+"이번에도 올바르지 않은 패스코드를 입력하면 휴대 전화를 공장 초기화하여 모든 "
301+"개인 정보를 삭제합니다."
297302
298303#: qml/Greeter/NarrowView.qml:116
299304#, qt-format
@@ -398,7 +403,7 @@ msgstr "실패, 두드리면 다시 시도합니다."
398403#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
399404msgctxt "Button: Send a reply message"
400405msgid "Send"
401−msgstr ""
406+msgstr "보내기"
402407
403408#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
404409msgctxt "Label: Hint in message indicator line edit"
@@ -408,7 +413,7 @@ msgstr "답신"
408413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
409414msgctxt "Button: Call back on phone"
410415msgid "Call back"
411−msgstr ""
416+msgstr "부재중 번호로 전화"
412417
413418#: qml/Panel/Indicators/ModemInfoItem.qml:105
414419msgid "Unlock SIM"
@@ -578,7 +583,8 @@ msgstr "GPS와 익명 와이파이 통신사 네트워크를 사용(추천)"
578583msgid ""
579584"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
580585"conditions</a>."
581−msgstr "이 옵션을 선택하면 자동으로 <a href='%1'>노키아 HERE 사용 조건에 동의합니다."
586+msgstr ""
587+"이 옵션을 선택하면 자동으로 <a href='%1'>노키아 HERE 사용 조건에 동의합니다."
582588
583589#: qml/Wizard/Pages/50-location.qml:112
584590msgid "Not at all"
@@ -596,13 +602,17 @@ msgstr "사용자 경험 개선"
596602msgid ""
597603"Your phone is set up to automatically report errors to Canonical and its "
598604"partners, the makers of the operating system."
599−msgstr "사용자의 전화를 자동으로 오류 보고를 운영 체제를 만든 캐노니컬 사와 협력사로 보내도록 설정했습니다."
605+msgstr ""
606+"사용자의 전화를 자동으로 오류 보고를 운영 체제를 만든 캐노니컬 사와 협력사로 "
607+"보내도록 설정했습니다."
600608
601609#: qml/Wizard/Pages/60-reporting.qml:53
602610msgid ""
603611"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
604612"Privacy</b>"
605−msgstr "이 서비스는 <b>보안 &amp; 사생활 보호</b>에서 언제든 사용하지 않도록 설정할 수 있습니다."
613+msgstr ""
614+"이 서비스는 <b>보안 &amp; 사생활 보호</b>에서 언제든 사용하지 않도록 설정할 "
615+"수 있습니다."
606616
607617#: qml/Wizard/Pages/80-finished.qml:24
608618msgid "All done"
@@ -657,6 +667,13 @@ msgstr "〈 %1"
657667msgid "%1 〉"
658668msgstr "%1 〉"
659669
670+#~ msgid ""
671+#~ "Your device is now connected to an external display. Use this screen as a "
672+#~ "touch pad to interact with the mouse."
673+#~ msgstr ""
674+#~ "장치를 외부 디스플레이와 연결햇습니다. 이 화면을 마우스와 상호작용 하는 터"
675+#~ "치 패드로 사용합니다."
676+
660677#~ msgid "Search"
661678#~ msgstr "검색"
662679
@@ -724,7 +741,8 @@ msgstr "%1 〉"
724741#~ "You have now mastered the edge gestures and can start using the "
725742#~ "phone<br><br>Tap on the screen to start"
726743#~ msgstr ""
727−#~ "여러분은 가장자리에서 끌어오기 제스쳐를 완벽히 익히셨고 휴대 전화를 사용할 수 있습니다. <br><br> 스크린을 터치해서 시작하세요."
744+#~ "여러분은 가장자리에서 끌어오기 제스쳐를 완벽히 익히셨고 휴대 전화를 사용"
745+#~ "할 수 있습니다. <br><br> 스크린을 터치해서 시작하세요."
728746
729747#~ msgid "Loading. Please Wait..."
730748#~ msgstr "불러오는 중 입니다. 짐시 기다려주십시오..."
po/ku.po+6−4
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-09-10 13:14+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Kurdish <ku@li.org>\n"
14+"Language: ku\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -713,7 +714,8 @@ msgstr ""
713714#~ msgstr "Kêleka çepê"
714715
715716#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
716−#~ msgstr "Ji bo vekirina gihînera lezgîn ya bernamokan ji kêleka çepê kaş bike"
717+#~ msgstr ""
718+#~ "Ji bo vekirina gihînera lezgîn ya bernamokan ji kêleka çepê kaş bike"
717719
718720#~ msgid ""
719721#~ "You have now mastered the edge gestures and can start using the "
po/ky.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-06-27 06:17+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kirghiz <ky@li.org>\n"
14+"Language: ky\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/lo.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-10-02 10:00+0000\n"
1212"Last-Translator: Anousak <anousak@gmail.com>\n"
1313"Language-Team: Lao <lo@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/lt.po+8−6
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-05-19 17:15+0000\n"
1212"Last-Translator: Mantas Kriaučiūnas <mantas@akl.lt>\n"
1313"Language-Team: Lithuanian <lt@li.org>\n"
14+"Language: lt\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"(n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
18+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
19+"%100<10 || n%100>=20) ? 1 : 2;\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -690,7 +691,8 @@ msgstr ""
690691#~ msgstr "Praleisti įžangą"
691692
692693#~ msgid "Try swiping from the right edge to unlock the phone"
693−#~ msgstr "Pabandykite braukti nuo dešiniojo krašto, kad atrakintumėte telefoną"
694+#~ msgstr ""
695+#~ "Pabandykite braukti nuo dešiniojo krašto, kad atrakintumėte telefoną"
694696
695697#~ msgid "Right edge"
696698#~ msgstr "Dešinysis kraštas"
po/lv.po+4−4
@@ -7,18 +7,18 @@
77msgid ""
88msgstr ""
99"Project-Id-Version: unity\n"
10−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"Report-Msgid-Bugs-To: \n"
1111"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1212"PO-Revision-Date: 2015-11-22 19:13+0000\n"
1313"Last-Translator: Klavs Anson <anson.klavs@gmail.com>\n"
1414"Language-Team: Latvian <lata-l10n@googlegroups.com>\n"
15+"Language: lv\n"
1516"MIME-Version: 1.0\n"
1617"Content-Type: text/plain; charset=UTF-8\n"
1718"Content-Transfer-Encoding: 8bit\n"
1819"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
21−"Language: lv\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2222
2323#: plugins/IntegratedLightDM/Greeter.cpp:112
2424msgid "Password: "
po/ml.po+5−5
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-11-23 11:44+0000\n"
1212"Last-Translator: ST Alfas <Unknown>\n"
1313"Language-Team: Malayalam <ml@li.org>\n"
14+"Language: ml\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -687,8 +688,7 @@ msgstr ""
687688
688689#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
689690#~ msgstr ""
690−#~ "പ്രയോഗങ്ങള്‍ പെട്ടെന്ന് ലഭ്യമാക്കുന്ന വിക്ഷേപിക ലഭ്യമാക്കാന്‍ ഇടതു വശത്ത് "
691−#~ "നിന്നും സ്വൈപ് ചെയ്യുക"
691+#~ "പ്രയോഗങ്ങള്‍ പെട്ടെന്ന് ലഭ്യമാക്കുന്ന വിക്ഷേപിക ലഭ്യമാക്കാന്‍ ഇടതു വശത്ത് നിന്നും സ്വൈപ് ചെയ്യുക"
692692
693693#~ msgid "Well done"
694694#~ msgstr "നന്നായി ചെയ്തിരിക്കുന്നു"
po/mr.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-01-14 19:54+0000\n"
1212"Last-Translator: Rohan Deshmukh <Unknown>\n"
1313"Language-Team: Marathi <mr@li.org>\n"
14+"Language: mr\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/ms.po+8−8
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-01-17 09:05+0000\n"
1212"Last-Translator: abuyop <Unknown>\n"
1313"Language-Team: Malay <ms@li.org>\n"
14+"Language: ms\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -511,8 +512,7 @@ msgstr "Tambah kad SIM dan mulakan semula peranti anda"
511512
512513#: qml/Wizard/Pages/20-sim.qml:59
513514msgid "Without it, you won’t be able to make calls or use text messaging."
514−msgstr ""
515−"Tanpanya, anda tidak boleh membuat panggilan atau guna pemesejan teks."
515+msgstr "Tanpanya, anda tidak boleh membuat panggilan atau guna pemesejan teks."
516516
517517#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
518518msgid "Skip"
@@ -582,8 +582,7 @@ msgstr "Hanya gunakan GPS (kurang tepat)"
582582
583583#: qml/Wizard/Pages/50-location.qml:86
584584msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
585−msgstr ""
586−"Gunakan GPS, Wi-Fi awanama dan maklumat rangkaian selular (disarankan)"
585+msgstr "Gunakan GPS, Wi-Fi awanama dan maklumat rangkaian selular (disarankan)"
587586
588587#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
589588#: qml/Wizard/Pages/50-location.qml:103
@@ -691,7 +690,8 @@ msgstr "%1 〉"
691690#~ msgstr "Pinggir kiri"
692691
693692#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
694−#~ msgstr "Leret dari kiri untuk munculkan pelancar untuk capaian pantas ke apl"
693+#~ msgstr ""
694+#~ "Leret dari kiri untuk munculkan pelancar untuk capaian pantas ke apl"
695695
696696#~ msgid "Well done"
697697#~ msgstr "Bagus"
po/my.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-12-12 11:12+0000\n"
1212"Last-Translator: Pyae Sone <Unknown>\n"
1313"Language-Team: Burmese <my@li.org>\n"
14+"Language: my\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/nb.po+16−13
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-05 19:44+0000\n"
1212"Last-Translator: Mathias Bynke <Unknown>\n"
1313"Language-Team: Norwegian Bokmal <nb@li.org>\n"
14+"Language: nb\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -29,7 +30,7 @@ msgstr "Fest snarvei"
2930
3031#: plugins/Unity/Launcher/launcheritem.cpp:52
3132msgid "Quit"
32−msgstr ""
33+msgstr "Avslutt"
3334
3435#: plugins/Unity/Launcher/launcheritem.cpp:106
3536msgid "Unpin shortcut"
@@ -153,27 +154,29 @@ msgstr "OK"
153154
154155#: qml/Components/ModeSwitchWarningDialog.qml:32
155156msgid "Apps may have unsaved data:"
156−msgstr ""
157+msgstr "Programmer kan ha ulagrede data:"
157158
158159#: qml/Components/ModeSwitchWarningDialog.qml:57
159160msgid "Re-dock, save your work and close these apps to continue."
160161msgstr ""
162+"Koble enheten til en stasjon, lagre arbeidet ditt og lukk disse programmene "
163+"for å fortsette."
161164
162165#: qml/Components/ModeSwitchWarningDialog.qml:63
163166msgid "Or force close now (unsaved data will be lost)."
164−msgstr ""
167+msgstr "Eller tving avslutning nå (ulagrede data går tapt)."
165168
166169#: qml/Components/ModeSwitchWarningDialog.qml:75
167170msgid "OK, I will reconnect"
168−msgstr ""
171+msgstr "OK, jeg skal koble til"
169172
170173#: qml/Components/ModeSwitchWarningDialog.qml:76
171174msgid "Reconnect now!"
172−msgstr ""
175+msgstr "Koble til nå!"
173176
174177#: qml/Components/ModeSwitchWarningDialog.qml:88
175178msgid "Close all"
176−msgstr ""
179+msgstr "Lukk alle"
177180
178181#: qml/Dash/DashPageHeader.qml:265
179182msgctxt "Button: Open the Ubuntu Store"
@@ -234,7 +237,7 @@ msgstr "Skriv en anmeldelse"
234237
235238#: qml/Dash/Previews/PreviewSharing.qml:51
236239msgid "Preview Share Item"
237−msgstr ""
240+msgstr "Forhåndsvis delingselement"
238241
239242#: qml/Dash/PullToRefreshScopeStyle.qml:55
240243msgid "Pull to refresh…"
@@ -329,7 +332,7 @@ msgstr "Feil passordfrase"
329332#: qml/Greeter/NarrowView.qml:121
330333msgctxt "passphrase"
331334msgid "Please re-enter"
332−msgstr ""
335+msgstr "Skriv inn på nytt"
333336
334337#: qml/Greeter/NarrowView.qml:122
335338msgid "Sorry, incorrect passcode"
@@ -410,7 +413,7 @@ msgstr "Feilet. Trykk for å prøve på nytt"
410413#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
411414msgctxt "Button: Send a reply message"
412415msgid "Send"
413−msgstr ""
416+msgstr "Send"
414417
415418#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
416419msgctxt "Label: Hint in message indicator line edit"
@@ -420,7 +423,7 @@ msgstr "Svar"
420423#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
421424msgctxt "Button: Call back on phone"
422425msgid "Call back"
423−msgstr ""
426+msgstr "Ring tilbake"
424427
425428#: qml/Panel/Indicators/ModemInfoItem.qml:105
426429msgid "Unlock SIM"
po/ne.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-12-06 15:11+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Nepali <ne@li.org>\n"
14+"Language: ne\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/nl.po+8−6
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-07 07:14+0000\n"
1212"Last-Translator: Hannie Dumoleyn <Unknown>\n"
1313"Language-Team: Dutch <nl@li.org>\n"
14+"Language: nl\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -717,7 +718,8 @@ msgstr "%1 〉"
717718#~ msgstr "Linkerrand"
718719
719720#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
720−#~ msgstr "Veeg vanaf links om de Starter te tonen voor snelle toegang tot apps"
721+#~ msgstr ""
722+#~ "Veeg vanaf links om de Starter te tonen voor snelle toegang tot apps"
721723
722724#~ msgid "Right edge"
723725#~ msgstr "Rechterrand"
@@ -726,8 +728,8 @@ msgstr "%1 〉"
726728#~ "You have now mastered the edge gestures and can start using the "
727729#~ "phone<br><br>Tap on the screen to start"
728730#~ msgstr ""
729−#~ "Nu u de bewegingen vanuit de randen onder de knie heeft, kunt u beginnen met "
730−#~ "het gebruiken van de telefoon<br><br>Tik op het scherm om te beginnen"
731+#~ "Nu u de bewegingen vanuit de randen onder de knie heeft, kunt u beginnen "
732+#~ "met het gebruiken van de telefoon<br><br>Tik op het scherm om te beginnen"
731733
732734#~ msgid "Try swiping from the top edge to access the indicators"
733735#~ msgstr "Veeg vanuit de bovenrand om de indicatoren te bekijken"
po/nn.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-05-12 11:32+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Norwegian Nynorsk <nn@li.org>\n"
14+"Language: nn\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/oc.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-02-05 20:35+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Occitan (post 1500) <oc@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/or.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-03-21 05:28+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Oriya <or@li.org>\n"
14+"Language: or\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n!=1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/pa.po+13−15
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-04-24 04:29+0000\n"
1212"Last-Translator: Gursharnjit_Singh <ubuntuser13@gmail.com>\n"
1313"Language-Team: Punjabi <pa@li.org>\n"
14+"Language: pa\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -291,16 +292,16 @@ msgid ""
291292"If passphrase is entered incorrectly, your phone will conduct a factory "
292293"reset and all personal data will be deleted."
293294msgstr ""
294−"ਜੇਕਰ ਗਲਤ ਵਾਕ ਦਰਜ ਹੋਇਆ, ਤੁਹਾਡਾ ਫ਼ੋਨ ਇੱਕ ਫ਼ੋਨ ਇੱਕ ਫ਼ੈਕਟਰੀ ਰੀਸੈੱਟ ਚਾਲੂ ਕਰੇਗਾ ਅਤੇ "
295−"ਸਾਰਾ ਨਿੱਜੀ ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"
295+"ਜੇਕਰ ਗਲਤ ਵਾਕ ਦਰਜ ਹੋਇਆ, ਤੁਹਾਡਾ ਫ਼ੋਨ ਇੱਕ ਫ਼ੋਨ ਇੱਕ ਫ਼ੈਕਟਰੀ ਰੀਸੈੱਟ ਚਾਲੂ ਕਰੇਗਾ ਅਤੇ ਸਾਰਾ ਨਿੱਜੀ ਡਾਟਾ "
296+"ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"
296297
297298#: qml/Greeter/NarrowView.qml:59
298299msgid ""
299300"If passcode is entered incorrectly, your phone will conduct a factory reset "
300301"and all personal data will be deleted."
301302msgstr ""
302−"ਜੇਕਰ ਗਲਤ ਪਾਸਕੋਡ ਦਰਜ ਹੋਇਆ, ਤੁਹਾਡਾ ਫ਼ੋਨ ਇੱਕ ਫ਼ੋਨ ਇੱਕ ਫ਼ੈਕਟਰੀ ਰੀਸੈੱਟ ਚਾਲੂ ਕਰੇਗਾ "
303−"ਅਤੇ ਸਾਰਾ ਨਿੱਜੀ ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"
303+"ਜੇਕਰ ਗਲਤ ਪਾਸਕੋਡ ਦਰਜ ਹੋਇਆ, ਤੁਹਾਡਾ ਫ਼ੋਨ ਇੱਕ ਫ਼ੋਨ ਇੱਕ ਫ਼ੈਕਟਰੀ ਰੀਸੈੱਟ ਚਾਲੂ ਕਰੇਗਾ ਅਤੇ ਸਾਰਾ ਨਿੱਜੀ "
304+"ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"
304305
305306#: qml/Greeter/NarrowView.qml:116
306307#, qt-format
@@ -523,8 +524,7 @@ msgstr "ਲਾਕ ਸੁਰੱਖਿਆ"
523524
524525#: qml/Wizard/Pages/30-passwd-type.qml:74
525526msgid "Please select how you’d like to unlock your phone."
526−msgstr ""
527−"ਕਿਰਪਾ ਕਰਕੇ ਚੁਣੋ ਤੁਸੀਂ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਕਿਸ ਤਰ੍ਹਾਂ ਅਣ-ਲਾਕ ਕਰਨਾ ਪਸੰਦ ਕਰੋਗੇ।"
527+msgstr "ਕਿਰਪਾ ਕਰਕੇ ਚੁਣੋ ਤੁਸੀਂ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਕਿਸ ਤਰ੍ਹਾਂ ਅਣ-ਲਾਕ ਕਰਨਾ ਪਸੰਦ ਕਰੋਗੇ।"
528528
529529#: qml/Wizard/Pages/30-passwd-type.qml:97
530530msgctxt "Label: Type of security method"
@@ -590,8 +590,7 @@ msgid ""
590590"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
591591"conditions</a>."
592592msgstr ""
593−"ਇਸ ਵਿਕਲਪ ਨੂੰ ਚੁਣਨ ਦੁਆਰਾ, ਤੁਸੀਂ ਨੋਕੀਆ HERE <a href='#'>ਨਿਯਮ ਅਤੇ ਸ਼ਰਤਾਂ</a>ਨੂੰ "
594−"ਪ੍ਰਵਾਨ ਕਰਦੇ ਹੋ।"
593+"ਇਸ ਵਿਕਲਪ ਨੂੰ ਚੁਣਨ ਦੁਆਰਾ, ਤੁਸੀਂ ਨੋਕੀਆ HERE <a href='#'>ਨਿਯਮ ਅਤੇ ਸ਼ਰਤਾਂ</a>ਨੂੰ ਪ੍ਰਵਾਨ ਕਰਦੇ ਹੋ।"
595594
596595#: qml/Wizard/Pages/50-location.qml:112
597596msgid "Not at all"
@@ -610,16 +609,15 @@ msgid ""
610609"Your phone is set up to automatically report errors to Canonical and its "
611610"partners, the makers of the operating system."
612611msgstr ""
613−"ਤੁਹਾਡੇ ਫ਼ੋਨ ਨੂੰ ਕੈਨੋਨੀਕਲ ਅਤੇ ਉਸਦੇ ਸਾਥੀਆਂ, ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਦੇ ਨਿਰਮਾਤਾਵਾਂ ਨੂੰ "
614−"ਆਪਣੇ ਆਪ ਖਾਮੀ ਸੂਚਨਾਵਾਂ ਭੇਜਣ ਲਈ ਸੈੱਟ ਕੀਤਾ ਗਿਆ ਹੈ।"
612+"ਤੁਹਾਡੇ ਫ਼ੋਨ ਨੂੰ ਕੈਨੋਨੀਕਲ ਅਤੇ ਉਸਦੇ ਸਾਥੀਆਂ, ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਦੇ ਨਿਰਮਾਤਾਵਾਂ ਨੂੰ ਆਪਣੇ ਆਪ ਖਾਮੀ ਸੂਚਨਾਵਾਂ "
613+"ਭੇਜਣ ਲਈ ਸੈੱਟ ਕੀਤਾ ਗਿਆ ਹੈ।"
615614
616615#: qml/Wizard/Pages/60-reporting.qml:53
617616msgid ""
618617"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
619618"Privacy</b>"
620619msgstr ""
621−"ਇਸ ਨੂੰ <b>ਸਿਸਟਮ ਸੈਟਿੰਗ</b> ਅਧੀਨ <b>ਸੁਰੱਖਿਆ &amp; ਪਰਦੇਦਾਰੀ</b>ਵਿੱਚ ਬੰਦ ਕੀਤਾ "
622−"ਜਾ ਸਕਦਾ"
620+"ਇਸ ਨੂੰ <b>ਸਿਸਟਮ ਸੈਟਿੰਗ</b> ਅਧੀਨ <b>ਸੁਰੱਖਿਆ &amp; ਪਰਦੇਦਾਰੀ</b>ਵਿੱਚ ਬੰਦ ਕੀਤਾ ਜਾ ਸਕਦਾ"
623621
624622#: qml/Wizard/Pages/80-finished.qml:24
625623msgid "All done"
po/pl.po+26−7
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-12 09:46+0000\n"
1212"Last-Translator: Seweryn Opyd <Unknown>\n"
1313"Language-Team: Polish <pl@li.org>\n"
14+"Language: pl\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
1819"|| n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -156,6 +157,8 @@ msgstr "Programy mogące mieć niezapisane dane:"
156157#: qml/Components/ModeSwitchWarningDialog.qml:57
157158msgid "Re-dock, save your work and close these apps to continue."
158159msgstr ""
160+"Aby kontynuować, dodaj ponownie do doku, zapisz swoją pracę i zamknij te "
161+"programy."
159162
160163#: qml/Components/ModeSwitchWarningDialog.qml:63
161164msgid "Or force close now (unsaved data will be lost)."
@@ -677,6 +680,22 @@ msgstr "〈 %1"
677680msgid "%1 〉"
678681msgstr "%1 〉"
679682
683+#~ msgid ""
684+#~ "Your device is now connected to an external display. Use this screen as a "
685+#~ "touch pad to interact with the mouse."
686+#~ msgstr ""
687+#~ "Twoje urządzenie jest teraz podłączone do zewnętrznego wyświetlacza. Użyj "
688+#~ "tego ekranu jako panelu dotykowego do interakcji z myszą."
689+
690+#~ msgid "Welcome to your Ubuntu device."
691+#~ msgstr "Witaj w swoim urządzeniu Ubuntu."
692+
693+#~ msgid "Please select how you’d like to unlock your device."
694+#~ msgstr "Prosimy wybrać sposób, w jaki chcesz odblokować swoje urządzenie."
695+
696+#~ msgid "Your device is now ready to use."
697+#~ msgstr "Twoje urządzenie jest już gotowe do użytku."
698+
680699#~ msgid "Confirm"
681700#~ msgstr "Potwierdź"
682701
@@ -715,8 +734,8 @@ msgstr "%1 〉"
715734
716735#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
717736#~ msgstr ""
718−#~ "Przeciągnięcie od lewej krawędzi, uruchamia aktywator szybkiego dostępu do "
719−#~ "aplikacji"
737+#~ "Przeciągnięcie od lewej krawędzi, uruchamia aktywator szybkiego dostępu "
738+#~ "do aplikacji"
720739
721740#~ msgid "Well done"
722741#~ msgstr "Udało się!"
@@ -731,8 +750,8 @@ msgstr "%1 〉"
731750#~ "You have now mastered the edge gestures and can start using the "
732751#~ "phone<br><br>Tap on the screen to start"
733752#~ msgstr ""
734−#~ "Wydawanie poleceń krawędzi zostało opanowane. Urządzenie gotowe do "
735−#~ "pracy.<br><br>Dotknij ekranu by rozpocząć"
753+#~ "Wydawanie poleceń krawędzi zostało opanowane. Urządzenie gotowe do pracy."
754+#~ "<br><br>Dotknij ekranu by rozpocząć"
736755
737756#~ msgid "Log out"
738757#~ msgstr "Wyloguj"
po/pt.po+31−13
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-12-20 09:20+0000\n"
11+"PO-Revision-Date: 2016-02-18 01:11+0000\n"
1212"Last-Translator: Ivo Xavier <ivofernandes12@gmail.com>\n"
1313"Language-Team: Portuguese <pt@li.org>\n"
14+"Language: pt\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-21 05:34+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -42,14 +43,14 @@ msgstr "Dispositivo bloqueado"
4243#: qml/Components/DelayedLockscreen.qml:64
4344msgid "You have been locked out due to too many failed passphrase attempts."
4445msgstr ""
45−"Está bloqueado devido a diversas tentativas falhadas na introdução da "
46−"palavra-passe."
46+"Está bloqueado por diversas tentativas falhadas na introdução da palavra-"
47+"passe."
4748
4849#: qml/Components/DelayedLockscreen.qml:65
4950msgid "You have been locked out due to too many failed passcode attempts."
5051msgstr ""
51−"Está bloqueado devido a diversas tentativas falhadas na introdução do código "
52−"de segurança."
52+"Está bloqueado por diversas tentativas falhadas na introdução do código de "
53+"segurança."
5354
5455#: qml/Components/DelayedLockscreen.qml:74
5556#, qt-format
@@ -143,7 +144,7 @@ msgstr "Reiniciar"
143144
144145#: qml/Components/Lockscreen.qml:245
145146msgid "Return to Call"
146−msgstr "Volte para chamada"
147+msgstr "Volte para a chamada"
147148
148149#: qml/Components/Lockscreen.qml:245
149150msgid "Emergency Call"
@@ -159,7 +160,7 @@ msgstr "Apps podem ter informação não guardada:"
159160
160161#: qml/Components/ModeSwitchWarningDialog.qml:57
161162msgid "Re-dock, save your work and close these apps to continue."
162−msgstr ""
163+msgstr "Volte a ligar, guarda o seu trabalho e feche as apps para continuar."
163164
164165#: qml/Components/ModeSwitchWarningDialog.qml:63
165166msgid "Or force close now (unsaved data will be lost)."
@@ -175,7 +176,7 @@ msgstr "Volte a ligar agora!"
175176
176177#: qml/Components/ModeSwitchWarningDialog.qml:88
177178msgid "Close all"
178−msgstr ""
179+msgstr "Fechar tudo"
179180
180181#: qml/Dash/DashPageHeader.qml:265
181182msgctxt "Button: Open the Ubuntu Store"
@@ -343,7 +344,7 @@ msgstr "Mostrar palavra-passe"
343344
344345#: qml/Panel/ActiveCallHint.qml:79
345346msgid "Tap to return to call..."
346−msgstr "Toque para voltar a chamar..."
347+msgstr "Toque para voltar à chamada..."
347348
348349#: qml/Panel/ActiveCallHint.qml:92
349350msgid "Conference"
@@ -678,6 +679,22 @@ msgstr "〈 %1"
678679msgid "%1 〉"
679680msgstr "%1 〉"
680681
682+#~ msgid ""
683+#~ "Your device is now connected to an external display. Use this screen as a "
684+#~ "touch pad to interact with the mouse."
685+#~ msgstr ""
686+#~ "O dispositivo está ligado a um ecrã externo. Utilize o ecrã como touchpad "
687+#~ "para manipular o ponteiro do rato."
688+
689+#~ msgid "Welcome to your Ubuntu device."
690+#~ msgstr "Bem-vindo ao seu dispositivo Ubuntu."
691+
692+#~ msgid "Please select how you’d like to unlock your device."
693+#~ msgstr "Escolha como quer desbloquear o seu dispositivo."
694+
695+#~ msgid "Your device is now ready to use."
696+#~ msgstr "O seu dispositivo está pronto."
697+
681698#~ msgid "Top edge"
682699#~ msgstr "Margem superior"
683700
@@ -794,7 +811,8 @@ msgstr "%1 〉"
794811
795812#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
796813#~ msgstr ""
797−#~ "Deslize da margem esquerda para mostrar o Launcher de acesso rápido às apps"
814+#~ "Deslize da margem esquerda para mostrar o Launcher de acesso rápido às "
815+#~ "apps"
798816
799817#~ msgid ""
800818#~ "You have now mastered the edge gestures and can start using the "
po/pt_BR.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-08-05 04:40+0000\n"
1212"Last-Translator: Julio Alexander Sieg <julio.sieg@gmail.com>\n"
1313"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
14+"Language: pt_BR\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/ro.po+6−7
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-06 17:47+0000\n"
1212"Last-Translator: Meriuță Cornel <meriutacornel@neacornel.eu>\n"
1313"Language-Team: Romanian <ro@li.org>\n"
14+"Language: ro\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
1819"== 0) && (n != 0))) ? 2: 1));\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -521,8 +522,7 @@ msgstr "Adăugați un card SIM și reporniți dispozitivul dumneavoastră"
521522
522523#: qml/Wizard/Pages/20-sim.qml:59
523524msgid "Without it, you won’t be able to make calls or use text messaging."
524−msgstr ""
525−"Fără acesta, nu veți putea efectua apeluri sau utiliza mesajele text."
525+msgstr "Fără acesta, nu veți putea efectua apeluri sau utiliza mesajele text."
526526
527527#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
528528msgid "Skip"
@@ -611,8 +611,7 @@ msgstr "Deloc"
611611
612612#: qml/Wizard/Pages/50-location.qml:124
613613msgid "You can change your mind later in <b>System Settings</b>."
614−msgstr ""
615−"Puteți să modificați opțiunea utilizând <b>Configurări de sistem</b>."
614+msgstr "Puteți să modificați opțiunea utilizând <b>Configurări de sistem</b>."
616615
617616#: qml/Wizard/Pages/60-reporting.qml:26
618617msgid "Improving your experience"
po/ru.po+11−10
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-06 05:33+0000\n"
1212"Last-Translator: ☠Jay ZDLin☠ <Unknown>\n"
1313"Language-Team: Russian <ru@li.org>\n"
14+"Language: ru\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
18+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -609,8 +610,7 @@ msgstr "Нет (никогда)"
609610
610611#: qml/Wizard/Pages/50-location.qml:124
611612msgid "You can change your mind later in <b>System Settings</b>."
612−msgstr ""
613−"Изменить свой выбор можно позднее, перейдя в <b>Параметры системы</b>."
613+msgstr "Изменить свой выбор можно позднее, перейдя в <b>Параметры системы</b>."
614614
615615#: qml/Wizard/Pages/60-reporting.qml:26
616616msgid "Improving your experience"
@@ -716,7 +716,8 @@ msgstr "%1 〉"
716716
717717#~ msgid "Try swiping from the top edge to access the indicators"
718718#~ msgstr ""
719−#~ "Попробуйте переместить палец от верхнего края вниз для доступа к индикаторам"
719+#~ "Попробуйте переместить палец от верхнего края вниз для доступа к "
720+#~ "индикаторам"
720721
721722#~ msgid "Close"
722723#~ msgstr "Закрыть"
@@ -735,8 +736,8 @@ msgstr "%1 〉"
735736
736737#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
737738#~ msgstr ""
738−#~ "Переместите палец от левого края вправо для открытия лаунчера для быстрого "
739−#~ "доступа к приложениям"
739+#~ "Переместите палец от левого края вправо для открытия лаунчера для "
740+#~ "быстрого доступа к приложениям"
740741
741742#~ msgid ""
742743#~ "You have now mastered the edge gestures and can start using the "
po/shn.po+18−18
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: \n"
10−"POT-Creation-Date: 2015-11-20 14:45+0100\n"
10+"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-11-10 12:09+0000\n"
1212"Last-Translator: Rockworld <sumoisrock@gmail.com>\n"
1313"Language-Team: Shan <shn@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Type: text/plain; charset=UTF-8\n"
1717"Content-Transfer-Encoding: 8bit\n"
1818"Plural-Forms: nplurals=2; plural=(n == 1) ? 0 : 1;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2121
2222#: plugins/IntegratedLightDM/Greeter.cpp:112
2323msgid "Password: "
@@ -195,15 +195,15 @@ msgstr ""
195195msgid "Add to Favorites"
196196msgstr ""
197197
198−#: qml/Dash/GenericScopeView.qml:569 qml/Dash/GenericScopeView.qml:727
198+#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
199199msgid "See less"
200200msgstr ""
201201
202−#: qml/Dash/GenericScopeView.qml:569
202+#: qml/Dash/GenericScopeView.qml:576
203203msgid "See all"
204204msgstr ""
205205
206−#: qml/Dash/GenericScopeView.qml:631
206+#: qml/Dash/GenericScopeView.qml:638
207207msgctxt "Label: Hint for dash search line edit"
208208msgid "Search"
209209msgstr ""
@@ -423,14 +423,6 @@ msgstr ""
423423msgid "Roaming"
424424msgstr ""
425425
426−#: qml/Tutorial/TutorialBottomFinish.qml:24
427−msgid "This action does different things for different apps"
428−msgstr ""
429−
430−#: qml/Tutorial/TutorialBottomFinish.qml:25
431−msgid "Tap here to finish."
432−msgstr ""
433−
434426#: qml/Tutorial/TutorialBottom.qml:28
435427msgid "Open special menus"
436428msgstr ""
@@ -439,15 +431,19 @@ msgstr ""
439431msgid "Swipe up from the bottom edge."
440432msgstr ""
441433
434+#: qml/Tutorial/TutorialBottomFinish.qml:24
435+msgid "This action does different things for different apps"
436+msgstr ""
437+
438+#: qml/Tutorial/TutorialBottomFinish.qml:25
439+msgid "Tap here to finish."
440+msgstr ""
441+
442442#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
443443#: qml/Tutorial/TutorialRight.qml:144
444444msgid "Tap here to continue."
445445msgstr ""
446446
447−#: qml/Tutorial/TutorialLeftFinish.qml:24
448−msgid "These are the shortcuts to favorite apps"
449−msgstr ""
450−
451447#: qml/Tutorial/TutorialLeft.qml:26
452448msgid "Open the launcher"
453449msgstr ""
@@ -456,6 +452,10 @@ msgstr ""
456452msgid "Short swipe from the left edge."
457453msgstr ""
458454
455+#: qml/Tutorial/TutorialLeftFinish.qml:24
456+msgid "These are the shortcuts to favorite apps"
457+msgstr ""
458+
459459#: qml/Tutorial/TutorialPage.qml:178
460460msgid "You almost got it!"
461461msgstr ""
po/si.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-06-26 22:36+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Sinhalese <si@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/sk.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-04-10 09:15+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Slovak <sk@li.org>\n"
14+"Language: sk\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/sl.po+58−18
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-07-06 21:10+0000\n"
12−"Last-Translator: Sasa Batistic <Unknown>\n"
11+"PO-Revision-Date: 2016-01-31 18:34+0000\n"
12+"Last-Translator: Bernard Banko <Unknown>\n"
1313"Language-Team: Slovenian <sl@li.org>\n"
14+"Language: sl\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
18−"n%100==4 ? 3 : 0);\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
18+"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
19+"%100==4 ? 3 : 0);\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -30,7 +31,7 @@ msgstr "Pripni bližnjico"
3031
3132#: plugins/Unity/Launcher/launcheritem.cpp:52
3233msgid "Quit"
33−msgstr ""
34+msgstr "Končaj"
3435
3536#: plugins/Unity/Launcher/launcheritem.cpp:106
3637msgid "Unpin shortcut"
@@ -150,31 +151,33 @@ msgstr "Klic v sili"
150151
151152#: qml/Components/Lockscreen.qml:277
152153msgid "OK"
153−msgstr "V REDU"
154+msgstr "V redu"
154155
155156#: qml/Components/ModeSwitchWarningDialog.qml:32
156157msgid "Apps may have unsaved data:"
157−msgstr ""
158+msgstr "Programi morda niso shranili podatkov:"
158159
159160#: qml/Components/ModeSwitchWarningDialog.qml:57
160161msgid "Re-dock, save your work and close these apps to continue."
161162msgstr ""
163+"Za nadaljevanje ponovno usidrajte, shranite svoje delo in zaprite te "
164+"programe."
162165
163166#: qml/Components/ModeSwitchWarningDialog.qml:63
164167msgid "Or force close now (unsaved data will be lost)."
165−msgstr ""
168+msgstr "Prisilno zapri sedaj (neshranjeni podatki bodo izgubljeni)."
166169
167170#: qml/Components/ModeSwitchWarningDialog.qml:75
168171msgid "OK, I will reconnect"
169−msgstr ""
172+msgstr "V redu, bom ponovno priključil"
170173
171174#: qml/Components/ModeSwitchWarningDialog.qml:76
172175msgid "Reconnect now!"
173−msgstr ""
176+msgstr "Ponovno priključi sedaj!"
174177
175178#: qml/Components/ModeSwitchWarningDialog.qml:88
176179msgid "Close all"
177−msgstr ""
180+msgstr "Zapri vse"
178181
179182#: qml/Dash/DashPageHeader.qml:265
180183msgctxt "Button: Open the Ubuntu Store"
@@ -235,7 +238,7 @@ msgstr "Dodaj oceno"
235238
236239#: qml/Dash/Previews/PreviewSharing.qml:51
237240msgid "Preview Share Item"
238−msgstr ""
241+msgstr "Preglej deljeno"
239242
240243#: qml/Dash/PullToRefreshScopeStyle.qml:55
241244msgid "Pull to refresh…"
@@ -330,7 +333,7 @@ msgstr "Oprostite, napačno šifrirno reklo"
330333#: qml/Greeter/NarrowView.qml:121
331334msgctxt "passphrase"
332335msgid "Please re-enter"
333−msgstr ""
336+msgstr "Ponovno vnesite"
334337
335338#: qml/Greeter/NarrowView.qml:122
336339msgid "Sorry, incorrect passcode"
@@ -417,7 +420,7 @@ msgstr "Spodletelo, tapnite za ponovni poskus"
417420#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
418421msgctxt "Button: Send a reply message"
419422msgid "Send"
420−msgstr ""
423+msgstr "Pošlji"
421424
422425#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
423426msgctxt "Label: Hint in message indicator line edit"
@@ -427,7 +430,7 @@ msgstr "Odgovor"
427430#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
428431msgctxt "Button: Call back on phone"
429432msgid "Call back"
430−msgstr ""
433+msgstr "Pokliči nazaj"
431434
432435#: qml/Panel/Indicators/ModemInfoItem.qml:105
433436msgid "Unlock SIM"
@@ -684,6 +687,13 @@ msgstr "〈 %1"
684687msgid "%1 〉"
685688msgstr "%1 〉"
686689
690+#~ msgid ""
691+#~ "Your device is now connected to an external display. Use this screen as a "
692+#~ "touch pad to interact with the mouse."
693+#~ msgstr ""
694+#~ "Vaša naprava je sedaj priključena na zunanji zaslon. Ta zaslon pa lahko "
695+#~ "uporabite kot sledilno ploščico za nadzor kazalke."
696+
687697#~ msgid "Confirm"
688698#~ msgstr "Potrdi"
689699
@@ -776,3 +786,33 @@ msgstr "%1 〉"
776786
777787#~ msgid "Please re-enter"
778788#~ msgstr "Ponovno vnesite"
789+
790+#~ msgid "%a %H:%M"
791+#~ msgstr "%a %H:%M"
792+
793+#~ msgid "%a %l:%M %p"
794+#~ msgstr "%a %l:%M %p"
795+
796+#~ msgid "Tomorrow %l:%M %p"
797+#~ msgstr "Jutri %l:%M %p"
798+
799+#~ msgid "%l:%M %p"
800+#~ msgstr "%l:%M %p"
801+
802+#~ msgid "Yesterday %l:%M %p"
803+#~ msgstr "Včeraj %l:%M %p"
804+
805+#~ msgid "%H:%M"
806+#~ msgstr "%H:%M"
807+
808+#~ msgid "Yesterday %H:%M"
809+#~ msgstr "Včeraj %H:%M"
810+
811+#~ msgid "Tomorrow %H:%M"
812+#~ msgstr "Jutri %H:%M"
813+
814+#~ msgid "%a %d %b %H:%M"
815+#~ msgstr "%a %d %b %H:%M"
816+
817+#~ msgid "%a %d %b %l:%M %p"
818+#~ msgstr "%a %d %b %l:%M %p"
po/sq.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-11-30 21:05+0000\n"
1212"Last-Translator: Indrit Bashkimi <indrit.bashkimi@gmail.com>\n"
1313"Language-Team: Albanian <sq@li.org>\n"
14+"Language: sq\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:44+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:03+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/sr.po+14−7
@@ -7,19 +7,19 @@
77msgid ""
88msgstr ""
99"Project-Id-Version: unity\n"
10−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"Report-Msgid-Bugs-To: \n"
1111"POT-Creation-Date: 2015-12-08 15:42+0000\n"
12−"PO-Revision-Date: 2015-12-09 20:16+0000\n"
12+"PO-Revision-Date: 2016-02-10 21:21+0000\n"
1313"Last-Translator: Bojan Bogdanović <Unknown>\n"
1414"Language-Team: српски <xfce4@xfce4.org>\n"
15+"Language: sr\n"
1516"MIME-Version: 1.0\n"
1617"Content-Type: text/plain; charset=UTF-8\n"
1718"Content-Transfer-Encoding: 8bit\n"
18−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
19−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
21−"X-Generator: Launchpad (build 17865)\n"
22−"Language: sr\n"
19+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
20+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
21+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
22+"X-Generator: Launchpad (build 17925)\n"
2323
2424#: plugins/IntegratedLightDM/Greeter.cpp:112
2525msgid "Password: "
@@ -682,6 +682,13 @@ msgstr "〈 %1"
682682msgid "%1 〉"
683683msgstr "%1 〉"
684684
685+#~ msgid ""
686+#~ "Your device is now connected to an external display. Use this screen as a "
687+#~ "touch pad to interact with the mouse."
688+#~ msgstr ""
689+#~ "Ваш уређај је сада повезан на спољњи монитор. Користите овај екран као "
690+#~ "додирну плочу да остварите интеракцију са мишем."
691+
685692#~ msgid "Confirm"
686693#~ msgstr "Потврди"
687694
po/sv.po+24−19
@@ -6,18 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-12 22:17+0000\n"
1212"Last-Translator: Josef Andersson <Unknown>\n"
1313"Language-Team: Swedish\n"
14+"Language: sv\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
20−"Language: sv\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2121
2222#: plugins/IntegratedLightDM/Greeter.cpp:112
2323msgid "Password: "
@@ -152,27 +152,27 @@ msgstr "OK"
152152
153153#: qml/Components/ModeSwitchWarningDialog.qml:32
154154msgid "Apps may have unsaved data:"
155−msgstr ""
155+msgstr "Program kan ha osparad data:"
156156
157157#: qml/Components/ModeSwitchWarningDialog.qml:57
158158msgid "Re-dock, save your work and close these apps to continue."
159−msgstr ""
159+msgstr "Docka om, spara ditt arbete och stäng dessa program för att fortsätta."
160160
161161#: qml/Components/ModeSwitchWarningDialog.qml:63
162162msgid "Or force close now (unsaved data will be lost)."
163−msgstr ""
163+msgstr "Eller tvinga avstängning nu (osparad data kommer att gå förlorad)."
164164
165165#: qml/Components/ModeSwitchWarningDialog.qml:75
166166msgid "OK, I will reconnect"
167−msgstr ""
167+msgstr "OK, jag kommer att återansluta"
168168
169169#: qml/Components/ModeSwitchWarningDialog.qml:76
170170msgid "Reconnect now!"
171−msgstr ""
171+msgstr "Återanslut nu!"
172172
173173#: qml/Components/ModeSwitchWarningDialog.qml:88
174174msgid "Close all"
175−msgstr ""
175+msgstr "Stäng alla"
176176
177177#: qml/Dash/DashPageHeader.qml:265
178178msgctxt "Button: Open the Ubuntu Store"
@@ -233,7 +233,7 @@ msgstr "Lägg till en recension"
233233
234234#: qml/Dash/Previews/PreviewSharing.qml:51
235235msgid "Preview Share Item"
236−msgstr ""
236+msgstr "Premiärvisa objektet dela"
237237
238238#: qml/Dash/PullToRefreshScopeStyle.qml:55
239239msgid "Pull to refresh…"
@@ -409,7 +409,7 @@ msgstr "Misslyckades, tryck för att försöka igen"
409409#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
410410msgctxt "Button: Send a reply message"
411411msgid "Send"
412−msgstr ""
412+msgstr "Skicka"
413413
414414#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
415415msgctxt "Label: Hint in message indicator line edit"
@@ -419,7 +419,7 @@ msgstr "Svara"
419419#: qml/Panel/Indicators/MessageMenuItemFactory.qml:213
420420msgctxt "Button: Call back on phone"
421421msgid "Call back"
422−msgstr ""
422+msgstr "Ring upp"
423423
424424#: qml/Panel/Indicators/ModemInfoItem.qml:105
425425msgid "Unlock SIM"
@@ -512,8 +512,7 @@ msgstr "Lägg till ett SIM-kort och starta om din enhet"
512512
513513#: qml/Wizard/Pages/20-sim.qml:59
514514msgid "Without it, you won’t be able to make calls or use text messaging."
515−msgstr ""
516−"Utan det kommer du inte att kunna ringa eller skicka textmeddelanden."
515+msgstr "Utan det kommer du inte att kunna ringa eller skicka textmeddelanden."
517516
518517#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
519518msgid "Skip"
@@ -583,8 +582,7 @@ msgstr "Använd endast GPS (sämre precision)"
583582
584583#: qml/Wizard/Pages/50-location.qml:86
585584msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
586−msgstr ""
587−"Använd GPS, anonymiserad Wi-Fi och mobil nätverksinfo (rekommenderas)"
585+msgstr "Använd GPS, anonymiserad Wi-Fi och mobil nätverksinfo (rekommenderas)"
588586
589587#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
590588#: qml/Wizard/Pages/50-location.qml:103
@@ -592,8 +590,8 @@ msgid ""
592590"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
593591"conditions</a>."
594592msgstr ""
595−"Genom att välja detta alternativ godkänner du <a "
596−"href='#'>användarvillkoren</a> för Nokia HERE."
593+"Genom att välja detta alternativ godkänner du <a href='#'>användarvillkoren</"
594+"a> för Nokia HERE."
597595
598596#: qml/Wizard/Pages/50-location.qml:112
599597msgid "Not at all"
@@ -676,6 +674,13 @@ msgstr "〈 %1"
676674msgid "%1 〉"
677675msgstr "%1 〉"
678676
677+#~ msgid ""
678+#~ "Your device is now connected to an external display. Use this screen as a "
679+#~ "touch pad to interact with the mouse."
680+#~ msgstr ""
681+#~ "Din enhet är nu ansluten till en extern display. Använd denna skärm som "
682+#~ "en styrplatta för att interagera med musen."
683+
679684#~ msgid "Top edge"
680685#~ msgstr "Överkant"
681686
po/sw.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-17 20:02+0000\n"
1212"Last-Translator: Valentine <mwangi_valentino@yahoo.com>\n"
1313"Language-Team: Swahili <sw@li.org>\n"
14+"Language: sw\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/ta.po+4−4
@@ -6,18 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-10-24 11:36+0000\n"
1212"Last-Translator: Arun Kumar - அருண் குமார் <thangam.arunx@gmail.com>\n"
1313"Language-Team: Ubuntu Tamil Team/Free Tamil Computing/Thamizha\n"
14+"Language: ta\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
20−"Language: ta\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2121
2222#: plugins/IntegratedLightDM/Greeter.cpp:112
2323msgid "Password: "
po/te.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-07-19 10:04+0000\n"
1212"Last-Translator: Praveen Illa <mail2ipn@gmail.com>\n"
1313"Language-Team: Telugu <te@li.org>\n"
14+"Language: te\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/th.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-10-02 04:55+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Thai <th@li.org>\n"
14+"Language: th\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/tr.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-03-22 15:56+0000\n"
1212"Last-Translator: Arda Ünlü <aarda.uunlu@gmail.com>\n"
1313"Language-Team: Turkish <tr@li.org>\n"
14+"Language: tr\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/ug.po+6−5
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-12-01 07:37+0000\n"
1212"Last-Translator: Eltikin <eltikinuyghur@hotmail.com>\n"
1313"Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -721,8 +722,8 @@ msgstr "%1 〉"
721722#~ "You have now mastered the edge gestures and can start using the "
722723#~ "phone<br><br>Tap on the screen to start"
723724#~ msgstr ""
724−#~ "ئېكراننى چېكىپ باشلاڭ<br><br>سىز ھازىر گىرۋەك بارماق ئىشارەتلىرىنى ئىگىلەپ "
725−#~ "بولدىڭىز،ئەمدى تېلېفوننى ئىشلىتىشنى باشلىسىڭىز بولىدۇ"
725+#~ "ئېكراننى چېكىپ باشلاڭ<br><br>سىز ھازىر گىرۋەك بارماق ئىشارەتلىرىنى "
726+#~ "ئىگىلەپ بولدىڭىز،ئەمدى تېلېفوننى ئىشلىتىشنى باشلىسىڭىز بولىدۇ"
726727
727728#~ msgid "Log out"
728729#~ msgstr "تىزىمدىن چىق"
po/uk.po+26−8
@@ -6,18 +6,19 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-04 05:53+0000\n"
1212"Last-Translator: Yuri Chornoivan <yurchor@gmail.com>\n"
1313"Language-Team: Ukrainian <uk@li.org>\n"
14+"Language: uk\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18−"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
20−"X-Generator: Launchpad (build 17865)\n"
18+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
21+"X-Generator: Launchpad (build 17925)\n"
2122
2223#: plugins/IntegratedLightDM/Greeter.cpp:112
2324msgid "Password: "
@@ -686,6 +687,22 @@ msgstr "〈 %1"
686687msgid "%1 〉"
687688msgstr "%1 〉"
688689
690+#~ msgid ""
691+#~ "Your device is now connected to an external display. Use this screen as a "
692+#~ "touch pad to interact with the mouse."
693+#~ msgstr ""
694+#~ "Ваш пристрій з’єднано із зовнішнім дисплеєм. Скористайтеся його екраном "
695+#~ "як сенсорною панеллю для імітації роботи із мишею."
696+
697+#~ msgid "Welcome to your Ubuntu device."
698+#~ msgstr "Вітаємо у вашому пристрої Ubuntu."
699+
700+#~ msgid "Please select how you’d like to unlock your device."
701+#~ msgstr "Будь ласка, виберіть спосіб розблокування вашого пристрою."
702+
703+#~ msgid "Your device is now ready to use."
704+#~ msgstr "Пристрій готовий до використання."
705+
689706#~ msgid "Confirm"
690707#~ msgstr "Підтвердити"
691708
@@ -732,7 +749,8 @@ msgstr "%1 〉"
732749#~ msgstr "Пропустити вступ"
733750
734751#~ msgid "Try swiping from the right edge to unlock the phone"
735−#~ msgstr "Спробуйте провести пальцем від правою краю, щоб розблокувати телефон"
752+#~ msgstr ""
753+#~ "Спробуйте провести пальцем від правою краю, щоб розблокувати телефон"
736754
737755#~ msgid "Right edge"
738756#~ msgstr "Правий край"
@@ -741,8 +759,8 @@ msgstr "%1 〉"
741759#~ "You have now mastered the edge gestures and can start using the "
742760#~ "phone<br><br>Tap on the screen to start"
743761#~ msgstr ""
744−#~ "Вами налаштовано дії у відповідь на дотики на краях екрана. Тепер телефоном "
745−#~ "можна користуватися.<br><br>Торкніться екрана, щоб розпочати."
762+#~ "Вами налаштовано дії у відповідь на дотики на краях екрана. Тепер "
763+#~ "телефоном можна користуватися.<br><br>Торкніться екрана, щоб розпочати."
746764
747765#~ msgid "All"
748766#~ msgstr "Все"
po/unity8.pot+40−38
@@ -1,6 +1,6 @@
11# SOME DESCRIPTIVE TITLE.
22# Copyright (C) YEAR Canonical Ltd.
3−# This file is distributed under the same license as the PACKAGE package.
3+# This file is distributed under the same license as the unity8 package.
44# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
55#
66#, fuzzy
@@ -8,7 +8,7 @@ msgid ""
88msgstr ""
99"Project-Id-Version: unity8\n"
1010"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11+"POT-Creation-Date: 2016-02-16 03:29+0000\n"
1212"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -171,38 +171,38 @@ msgstr ""
171171msgid "Close all"
172172msgstr ""
173173
174−#: qml/Dash/DashPageHeader.qml:265
174+#: qml/Dash/DashPageHeader.qml:266
175175msgctxt "Button: Open the Ubuntu Store"
176176msgid "Store"
177177msgstr ""
178178
179−#: qml/Dash/DashPageHeader.qml:272
179+#: qml/Dash/DashPageHeader.qml:273
180180msgctxt "Button: Start a search in the current dash scope"
181181msgid "Search"
182182msgstr ""
183183
184−#: qml/Dash/DashPageHeader.qml:282
184+#: qml/Dash/DashPageHeader.qml:283
185185msgctxt "Button: Show the current dash scope settings"
186186msgid "Settings"
187187msgstr ""
188188
189−#: qml/Dash/DashPageHeader.qml:289
189+#: qml/Dash/DashPageHeader.qml:290
190190msgid "Remove from Favorites"
191191msgstr ""
192192
193−#: qml/Dash/DashPageHeader.qml:289
193+#: qml/Dash/DashPageHeader.qml:290
194194msgid "Add to Favorites"
195195msgstr ""
196196
197−#: qml/Dash/GenericScopeView.qml:576 qml/Dash/GenericScopeView.qml:734
197+#: qml/Dash/GenericScopeView.qml:587 qml/Dash/GenericScopeView.qml:745
198198msgid "See less"
199199msgstr ""
200200
201−#: qml/Dash/GenericScopeView.qml:576
201+#: qml/Dash/GenericScopeView.qml:587
202202msgid "See all"
203203msgstr ""
204204
205−#: qml/Dash/GenericScopeView.qml:638
205+#: qml/Dash/GenericScopeView.qml:649
206206msgctxt "Label: Hint for dash search line edit"
207207msgid "Search"
208208msgstr ""
@@ -228,7 +228,7 @@ msgstr ""
228228msgid "Add a review"
229229msgstr ""
230230
231−#: qml/Dash/Previews/PreviewSharing.qml:51
231+#: qml/Dash/Previews/PreviewSharing.qml:50
232232msgid "Preview Share Item"
233233msgstr ""
234234
@@ -256,19 +256,21 @@ msgstr ""
256256msgid "Also installed"
257257msgstr ""
258258
259−#: qml/DisabledScreenNotice.qml:42
260−msgid "Your device is now connected to an external display."
259+#: qml/DisabledScreenNotice.qml:87
260+msgid ""
261+"Your device is now connected to an external display. Use this screen as a "
262+"touch pad to interact with the mouse."
261263msgstr ""
262264
263265#: qml/Greeter/CoverPage.qml:107
264266msgid "Unlock"
265267msgstr ""
266268
267−#: qml/Greeter/LoginList.qml:236
269+#: qml/Greeter/LoginList.qml:239
268270msgid "Retry"
269271msgstr ""
270272
271−#: qml/Greeter/LoginList.qml:237
273+#: qml/Greeter/LoginList.qml:240
272274msgid "Tap to unlock"
273275msgstr ""
274276
@@ -339,62 +341,62 @@ msgstr ""
339341msgid "Conference"
340342msgstr ""
341343
342−#: qml/Panel/Indicators/MenuItemFactory.qml:731
344+#: qml/Panel/Indicators/MenuItemFactory.qml:753
343345msgid "Nothing is playing"
344346msgstr ""
345347
346−#: qml/Panel/Indicators/MenuItemFactory.qml:860
348+#: qml/Panel/Indicators/MenuItemFactory.qml:882
347349#, qt-format
348350msgid "%1 hour"
349351msgid_plural "%1 hours"
350352msgstr[0] ""
351353msgstr[1] ""
352354
353−#: qml/Panel/Indicators/MenuItemFactory.qml:864
355+#: qml/Panel/Indicators/MenuItemFactory.qml:886
354356#, qt-format
355357msgid "%1 minute"
356358msgid_plural "%1 minutes"
357359msgstr[0] ""
358360msgstr[1] ""
359361
360−#: qml/Panel/Indicators/MenuItemFactory.qml:869
362+#: qml/Panel/Indicators/MenuItemFactory.qml:891
361363#, qt-format
362364msgid "%1 second"
363365msgid_plural "%1 seconds"
364366msgstr[0] ""
365367msgstr[1] ""
366368
367−#: qml/Panel/Indicators/MenuItemFactory.qml:872
369+#: qml/Panel/Indicators/MenuItemFactory.qml:894
368370msgid "0 seconds"
369371msgstr ""
370372
371373#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
372−#: qml/Panel/Indicators/MenuItemFactory.qml:874
374+#: qml/Panel/Indicators/MenuItemFactory.qml:896
373375#, qt-format
374376msgid "%1 remaining"
375377msgstr ""
376378
377−#: qml/Panel/Indicators/MenuItemFactory.qml:880
379+#: qml/Panel/Indicators/MenuItemFactory.qml:902
378380msgid "In queue…"
379381msgstr ""
380382
381−#: qml/Panel/Indicators/MenuItemFactory.qml:884
383+#: qml/Panel/Indicators/MenuItemFactory.qml:906
382384msgid "Downloading"
383385msgstr ""
384386
385−#: qml/Panel/Indicators/MenuItemFactory.qml:886
387+#: qml/Panel/Indicators/MenuItemFactory.qml:908
386388msgid "Paused, tap to resume"
387389msgstr ""
388390
389−#: qml/Panel/Indicators/MenuItemFactory.qml:888
391+#: qml/Panel/Indicators/MenuItemFactory.qml:910
390392msgid "Canceled"
391393msgstr ""
392394
393−#: qml/Panel/Indicators/MenuItemFactory.qml:890
395+#: qml/Panel/Indicators/MenuItemFactory.qml:912
394396msgid "Finished"
395397msgstr ""
396398
397−#: qml/Panel/Indicators/MenuItemFactory.qml:892
399+#: qml/Panel/Indicators/MenuItemFactory.qml:914
398400msgid "Failed, tap to retry"
399401msgstr ""
400402
@@ -485,14 +487,14 @@ msgid "Hi!"
485487msgstr ""
486488
487489#: qml/Wizard/Pages/10-welcome.qml:44
488−msgid "Welcome to your Ubuntu phone."
490+msgid "Welcome to your Ubuntu device."
489491msgstr ""
490492
491493#: qml/Wizard/Pages/10-welcome.qml:52
492494msgid "Let’s get started."
493495msgstr ""
494496
495−#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
497+#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:133
496498#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
497499#: qml/Wizard/Pages/60-reporting.qml:60 qml/Wizard/Pages/passwd-confirm.qml:82
498500#: qml/Wizard/Pages/passwd-set.qml:90
@@ -515,36 +517,36 @@ msgstr ""
515517msgid "Lock security"
516518msgstr ""
517519
518−#: qml/Wizard/Pages/30-passwd-type.qml:74
519−msgid "Please select how you’d like to unlock your phone."
520+#: qml/Wizard/Pages/30-passwd-type.qml:79
521+msgid "Please select how you’d like to unlock your device."
520522msgstr ""
521523
522−#: qml/Wizard/Pages/30-passwd-type.qml:97
524+#: qml/Wizard/Pages/30-passwd-type.qml:102
523525msgctxt "Label: Type of security method"
524526msgid "Swipe"
525527msgstr ""
526528
527−#: qml/Wizard/Pages/30-passwd-type.qml:98
529+#: qml/Wizard/Pages/30-passwd-type.qml:103
528530msgctxt "Label: Description of security method"
529531msgid "No security"
530532msgstr ""
531533
532−#: qml/Wizard/Pages/30-passwd-type.qml:100
534+#: qml/Wizard/Pages/30-passwd-type.qml:105
533535msgctxt "Label: Type of security method"
534536msgid "Passcode"
535537msgstr ""
536538
537−#: qml/Wizard/Pages/30-passwd-type.qml:101
539+#: qml/Wizard/Pages/30-passwd-type.qml:106
538540msgctxt "Label: Description of security method"
539541msgid "4 digits only"
540542msgstr ""
541543
542−#: qml/Wizard/Pages/30-passwd-type.qml:103
544+#: qml/Wizard/Pages/30-passwd-type.qml:108
543545msgctxt "Label: Type of security method"
544546msgid "Passphrase"
545547msgstr ""
546548
547−#: qml/Wizard/Pages/30-passwd-type.qml:104
549+#: qml/Wizard/Pages/30-passwd-type.qml:109
548550msgctxt "Label: Description of security method"
549551msgid "Numbers and letters"
550552msgstr ""
@@ -617,7 +619,7 @@ msgid "Nice work!"
617619msgstr ""
618620
619621#: qml/Wizard/Pages/80-finished.qml:46
620−msgid "Your phone is now ready to use."
622+msgid "Your device is now ready to use."
621623msgstr ""
622624
623625#: qml/Wizard/Pages/80-finished.qml:53
po/ur.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-05-05 03:12+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Urdu <ur@li.org>\n"
14+"Language: ur\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/uz.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-04 16:03+0000\n"
1212"Last-Translator: Learner <muzaffar.habibullayev@yandex.ru>\n"
1313"Language-Team: Uzbek <uz@li.org>\n"
14+"Language: uz\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/vi.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-01-15 01:19+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Vietnamese <vi@li.org>\n"
14+"Language: vi\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/wo.po+7−7
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-10-29 11:16+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Wolof <wo@li.org>\n"
14+"Language: wo\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -579,8 +580,7 @@ msgstr "Ci jëfandikoo GPS kepp (gën a ñawadi)"
579580
580581#: qml/Wizard/Pages/50-location.qml:86
581582msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
582−msgstr ""
583−"Jëfandikoo GPS, wi-fi buñ xamul ak xibaaru mbaalu wootekaay (digalees)"
583+msgstr "Jëfandikoo GPS, wi-fi buñ xamul ak xibaaru mbaalu wootekaay (digalees)"
584584
585585#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
586586#: qml/Wizard/Pages/50-location.qml:103
@@ -729,8 +729,8 @@ msgstr "%1 〉"
729729#~ "You have now mastered the edge gestures and can start using the "
730730#~ "phone<br><br>Tap on the screen to start"
731731#~ msgstr ""
732−#~ "Léegi nàng nga bu baax kon man nga tàmbali jëfandikoo wootekaay bi <br><br> "
733−#~ "Bësal ci xoolu bi ngir tàmbali"
732+#~ "Léegi nàng nga bu baax kon man nga tàmbali jëfandikoo wootekaay bi "
733+#~ "<br><br> Bësal ci xoolu bi ngir tàmbali"
734734
735735#~ msgid "Store"
736736#~ msgstr "Ja"
po/xh.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2013-09-28 13:20+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Xhosa <xh@li.org>\n"
14+"Language: xh\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/zh_CN.po+27−7
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2015-07-27 10:26+0000\n"
1212"Last-Translator: Ian Li <Unknown>\n"
1313"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
14+"Language: \n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
@@ -289,13 +290,15 @@ msgstr "这是您最后的尝试机会。"
289290msgid ""
290291"If passphrase is entered incorrectly, your phone will conduct a factory "
291292"reset and all personal data will be deleted."
292−msgstr "如果输入的密语不正确,您的手机将恢复到出厂设置并且所有的个人数据将被删除。"
293+msgstr ""
294+"如果输入的密语不正确,您的手机将恢复到出厂设置并且所有的个人数据将被删除。"
293295
294296#: qml/Greeter/NarrowView.qml:59
295297msgid ""
296298"If passcode is entered incorrectly, your phone will conduct a factory reset "
297299"and all personal data will be deleted."
298−msgstr "如果输入的密码不正确,您的手机将恢复到出厂设置并且所有的个人数据将被删除。"
300+msgstr ""
301+"如果输入的密码不正确,您的手机将恢复到出厂设置并且所有的个人数据将被删除。"
299302
300303#: qml/Greeter/NarrowView.qml:116
301304#, qt-format
@@ -598,7 +601,8 @@ msgstr "改善您的体验"
598601msgid ""
599602"Your phone is set up to automatically report errors to Canonical and its "
600603"partners, the makers of the operating system."
601−msgstr "您的手机设置为自动向操作系统的制造商Canonical 及其合作伙伴发送错误报告。"
604+msgstr ""
605+"您的手机设置为自动向操作系统的制造商Canonical 及其合作伙伴发送错误报告。"
602606
603607#: qml/Wizard/Pages/60-reporting.qml:53
604608msgid ""
@@ -659,6 +663,21 @@ msgstr "〈 %1"
659663msgid "%1 〉"
660664msgstr "%1 〉"
661665
666+#~ msgid ""
667+#~ "Your device is now connected to an external display. Use this screen as a "
668+#~ "touch pad to interact with the mouse."
669+#~ msgstr ""
670+#~ "你的设备现已连接上了一个外接显示。将这个屏幕作为触控板使用,可与鼠标互动。"
671+
672+#~ msgid "Welcome to your Ubuntu device."
673+#~ msgstr "欢迎使用您的Ubuntu设备。"
674+
675+#~ msgid "Please select how you’d like to unlock your device."
676+#~ msgstr "请选择你偏好的设备解锁方式。"
677+
678+#~ msgid "Your device is now ready to use."
679+#~ msgstr "您的设备已就绪。"
680+
662681#~ msgid "Confirm"
663682#~ msgstr "确认"
664683
@@ -710,7 +729,8 @@ msgstr "%1 〉"
710729#~ msgid ""
711730#~ "You have now mastered the edge gestures and can start using the "
712731#~ "phone<br><br>Tap on the screen to start"
713−#~ msgstr "您现在已经掌握了边缘滑动手势,可以开始使用手机了<br><br>请点击屏幕开始使用"
732+#~ msgstr ""
733+#~ "您现在已经掌握了边缘滑动手势,可以开始使用手机了<br><br>请点击屏幕开始使用"
714734
715735#~ msgid "All"
716736#~ msgstr "所有"
po/zh_HK.po+4−3
@@ -6,17 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
1111"PO-Revision-Date: 2014-08-10 11:45+0000\n"
1212"Last-Translator: Daniel Cheung <daniel.2345@hotmail.com>\n"
1313"Language-Team: Chinese (Hong Kong) <zh_HK@li.org>\n"
14+"Language: zh_HK\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
19+"X-Launchpad-Export-Date: 2016-02-23 06:04+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2021
2122#: plugins/IntegratedLightDM/Greeter.cpp:112
2223msgid "Password: "
po/zh_TW.po+23−12
@@ -6,18 +6,18 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
1010"POT-Creation-Date: 2015-12-08 15:42+0000\n"
11−"PO-Revision-Date: 2015-07-31 09:29+0000\n"
11+"PO-Revision-Date: 2016-02-24 04:40+0000\n"
1212"Last-Translator: Po-Hsu Lin <po-hsu.lin@canonical.com>\n"
1313"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
14+"Language: zh_TW\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
1718"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-12-12 05:45+0000\n"
19−"X-Generator: Launchpad (build 17865)\n"
20−"Language: zh_TW\n"
19+"X-Launchpad-Export-Date: 2016-02-25 05:23+0000\n"
20+"X-Generator: Launchpad (build 17925)\n"
2121
2222#: plugins/IntegratedLightDM/Greeter.cpp:112
2323msgid "Password: "
@@ -153,19 +153,19 @@ msgstr "可能未儲存資料的程式:"
153153
154154#: qml/Components/ModeSwitchWarningDialog.qml:57
155155msgid "Re-dock, save your work and close these apps to continue."
156−msgstr ""
156+msgstr "重新靠鎖,儲存您的工作項目及關閉相關應用程式後繼續."
157157
158158#: qml/Components/ModeSwitchWarningDialog.qml:63
159159msgid "Or force close now (unsaved data will be lost)."
160−msgstr ""
160+msgstr "或強制關閉 (未儲存的資料即將遺失)"
161161
162162#: qml/Components/ModeSwitchWarningDialog.qml:75
163163msgid "OK, I will reconnect"
164−msgstr ""
164+msgstr "好的,我將重新連線"
165165
166166#: qml/Components/ModeSwitchWarningDialog.qml:76
167167msgid "Reconnect now!"
168−msgstr ""
168+msgstr "即刻重新連線!"
169169
170170#: qml/Components/ModeSwitchWarningDialog.qml:88
171171msgid "Close all"
@@ -230,7 +230,7 @@ msgstr "新增評論"
230230
231231#: qml/Dash/Previews/PreviewSharing.qml:51
232232msgid "Preview Share Item"
233−msgstr ""
233+msgstr "預覽分享的項目"
234234
235235#: qml/Dash/PullToRefreshScopeStyle.qml:55
236236msgid "Pull to refresh…"
@@ -399,7 +399,7 @@ msgstr "失敗,點按可重試"
399399#: qml/Panel/Indicators/MessageMenuItemFactory.qml:214
400400msgctxt "Button: Send a reply message"
401401msgid "Send"
402−msgstr ""
402+msgstr "傳送"
403403
404404#: qml/Panel/Indicators/MessageMenuItemFactory.qml:156
405405msgctxt "Label: Hint in message indicator line edit"
@@ -597,7 +597,9 @@ msgstr "改善您的使用體驗"
597597msgid ""
598598"Your phone is set up to automatically report errors to Canonical and its "
599599"partners, the makers of the operating system."
600−msgstr "您的手機已設置為會自動向 Canonical 及其合作夥伴 (作業系統的製作者) 回報錯誤問題。"
600+msgstr ""
601+"您的手機已設置為會自動向 Canonical 及其合作夥伴 (作業系統的製作者) 回報錯誤問"
602+"題。"
601603
602604#: qml/Wizard/Pages/60-reporting.qml:53
603605msgid ""
@@ -658,6 +660,15 @@ msgstr "〈 %1"
658660msgid "%1 〉"
659661msgstr "%1 〉"
660662
663+#~ msgid "Welcome to your Ubuntu device."
664+#~ msgstr "歡迎使用您的 Ubuntu 裝置"
665+
666+#~ msgid "Please select how you’d like to unlock your device."
667+#~ msgstr "請選擇您想要的裝置解鎖方式。"
668+
669+#~ msgid "Your device is now ready to use."
670+#~ msgstr "您的裝置已準備就緒。"
671+
661672#~ msgid "Confirm"
662673#~ msgstr "確認"
663674
qml/Components/EdgeBarrierController.qml+2
@@ -30,6 +30,8 @@ MouseArea {
3030 // Should trigger the action associated with this edge
3131 signal passed()
3232
33+ onPressed: mouse.accepted = false;
34+
3335 function push(amount) {
3436 if (!root._containsMouse) {
3537 return;
qml/Components/InputMethod.qml+1−1
@@ -59,7 +59,7 @@ Item {
5959 }
6060
6161 state: {
62− if (surfaceItem.surface && surfaceItem.surfaceState != Mir.MinimizedState) {
62+ if (surfaceItem.surface && surfaceItem.surfaceState != Mir.MinimizedState && root.enabled) {
6363 return "shown";
6464 } else {
6565 return "hidden";
qml/Components/PhysicalKeysMapper.qml+32−2
@@ -16,6 +16,7 @@
1616
1717import QtQuick 2.4
1818import Powerd 0.1
19+import Utils 0.1
1920
2021/*!
2122 \brief A mapper for the physical keys on the device
@@ -59,9 +60,24 @@ Item {
5960 property bool altTabPressed: false
6061
6162 property var powerButtonPressStart: 0
63+
64+ // We need to eat ALT presses until we know what they're for (Alt+Tab or going to the app?)
65+ // Once we know if an ALT keypress is for the app, we need to re-inject the pressed event for it
66+ // but we must only do that once.
67+ property bool altPressInjected: false
68+ }
69+
70+ InputEventGenerator {
71+ id: inputEventGenerator
6272 }
6373
6474 function onKeyPressed(event, currentEventTimestamp) {
75+ if (d.altPressed && !d.altTabPressed && event.key !== Qt.Key_Tab && event.key !== Qt.Key_Alt && !d.altPressInjected) {
76+ // ALT is pressed and another key that is not Tab has been received. Re-inject the alt pressed event
77+ d.altPressInjected = true;
78+ inputEventGenerator.generateKeyEvent(Qt.Key_Alt, true, Qt.NoModifier, currentEventTimestamp - 1, 56);
79+ }
80+
6581 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
6682 if (event.isAutoRepeat) {
6783 if (d.powerButtonPressStart > 0
@@ -97,7 +113,12 @@ Item {
97113 d.volumeUpKeyPressed = true;
98114 }
99115 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
100− d.altPressed = true;
116+ if (!d.altPressed || event.isAutoRepeat) {
117+ // Only eat it if it's the first time we receive alt pressed (or if it's the autorepeat of the first press)
118+ d.altPressed = true;
119+ event.accepted = true;
120+ d.altPressInjected = false;
121+ }
101122 } else if (event.key == Qt.Key_Tab) {
102123 if (d.altPressed && !d.altTabPressed) {
103124 d.altTabPressed = true;
@@ -119,10 +140,19 @@ Item {
119140 d.volumeUpKeyPressed = false;
120141 if (!d.volumeDownKeyPressed) d.ignoreVolumeEvents = false;
121142 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
122− d.altPressed = false;
123143 if (d.altTabPressed) {
124144 d.altTabPressed = false;
125145 event.accepted = true;
146+ } else if (d.altPressed && !d.altPressInjected) {
147+ // Alt was released but nothing else. Let's inject a pressed event and also forward the release.
148+ d.altPressInjected = true;
149+ inputEventGenerator.generateKeyEvent(Qt.Key_Alt, true, Qt.AltModifer, currentEventTimestamp, 56);
150+ d.altPressInjected = false;
151+ }
152+ d.altPressed = false;
153+ } else if (event.key == Qt.Key_Tab) {
154+ if (d.altTabPressed) {
155+ event.accepted = true;
126156 }
127157 }
128158 }
qml/Components/ResponsiveGridView.qml+2−4
@@ -18,12 +18,10 @@ import QtQuick 2.4
1818import Ubuntu.Components 1.3
1919
2020/*
21− Essentially a GridView where you can specify the maximum number of columns it can have.
21+ Essentially a GridView
2222 */
2323Item {
2424 property int minimumHorizontalSpacing: units.gu(0.5)
25− // property int minimumNumberOfColumns: 2 // FIXME: not implemented
26− property int maximumNumberOfColumns: 6
2725 readonly property int columns: gridView.columns
2826 property alias verticalSpacing: gridView.verticalSpacing
2927 readonly property alias margins: gridView.margin
@@ -81,7 +79,7 @@ Item {
8179 }
8280
8381 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
84− property int columns: Math.min(columnsForSpacing(minimumHorizontalSpacing), maximumNumberOfColumns)
82+ property int columns: columnsForSpacing(minimumHorizontalSpacing)
8583 property real horizontalSpacing: spacingForColumns(columns)
8684 property real verticalSpacing: horizontalSpacing
8785 property int margin: allocatableHorizontalSpace - columns * horizontalSpacing
qml/Components/VirtualTouchPad.qmlnew file+138
@@ -0,0 +1,138 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import UInput 0.1
20+
21+Item {
22+ property var uinput: UInput {
23+ Component.onCompleted: createMouse();
24+ Component.onDestruction: removeMouse();
25+ }
26+
27+ readonly property bool pressed: point1.pressed || point2.pressed
28+
29+ MultiPointTouchArea {
30+ objectName: "touchPadArea"
31+ anchors.fill: parent
32+
33+ // FIXME: Once we have Qt DPR support, this should be Qt.styleHints.startDragDistance
34+ readonly property int clickThreshold: units.gu(1.5)
35+ property bool isClick: false
36+ property bool isDoubleClick: false
37+ property bool isDrag: false
38+
39+ onPressed: {
40+ // If double-tapping *really* fast, it could happen that we end up having only point2 pressed
41+ // Make sure we check for both combos, only point1 or only point2
42+ if (((point1.pressed && !point2.pressed) || (!point1.pressed && point2.pressed))
43+ && clickTimer.running) {
44+ clickTimer.stop();
45+ uinput.pressMouse(UInput.ButtonLeft)
46+ isDoubleClick = true;
47+ }
48+ isClick = true;
49+ }
50+
51+ onUpdated: {
52+ switch (touchPoints.length) {
53+ case 1:
54+ moveMouse(touchPoints);
55+ return;
56+ case 2:
57+ scroll(touchPoints);
58+ return;
59+ }
60+ }
61+
62+ onReleased: {
63+ if (isDoubleClick || isDrag) {
64+ uinput.releaseMouse(UInput.ButtonLeft)
65+ isDoubleClick = false;
66+ }
67+ if (isClick) {
68+ clickTimer.scheduleClick(point1.pressed ? UInput.ButtonRight : UInput.ButtonLeft)
69+ }
70+ isClick = false;
71+ isDrag = false;
72+ }
73+
74+ Timer {
75+ id: clickTimer
76+ repeat: false
77+ interval: 200
78+ property int button: UInput.ButtonLeft
79+ onTriggered: {
80+ uinput.pressMouse(button);
81+ uinput.releaseMouse(button);
82+ }
83+ function scheduleClick(button) {
84+ clickTimer.button = button;
85+ clickTimer.start();
86+ }
87+ }
88+
89+ function moveMouse(touchPoints) {
90+ var tp = touchPoints[0];
91+ if (isClick &&
92+ (Math.abs(tp.x - tp.startX) > clickThreshold ||
93+ Math.abs(tp.y - tp.startY) > clickThreshold)) {
94+ isClick = false;
95+ isDrag = true;
96+ }
97+
98+ uinput.moveMouse(tp.x - tp.previousX, tp.y - tp.previousY);
99+ }
100+
101+ function scroll(touchPoints) {
102+ var dh = 0;
103+ var dv = 0;
104+ var tp = touchPoints[0];
105+ if (isClick &&
106+ (Math.abs(tp.x - tp.startX) > clickThreshold ||
107+ Math.abs(tp.y - tp.startY) > clickThreshold)) {
108+ isClick = false;
109+ }
110+ dh += tp.x - tp.previousX;
111+ dv += tp.y - tp.previousY;
112+
113+ tp = touchPoints[1];
114+ if (isClick &&
115+ (Math.abs(tp.x - tp.startX) > clickThreshold ||
116+ Math.abs(tp.y - tp.startY) > clickThreshold)) {
117+ isClick = false;
118+ }
119+ dh += tp.x - tp.previousX;
120+ dv += tp.y - tp.previousY;
121+
122+ // As we added up the movement of the two fingers, let's divide it again by 2
123+ dh /= 2;
124+ dv /= 2;
125+
126+ uinput.scrollMouse(dh, dv);
127+ }
128+
129+ touchPoints: [
130+ TouchPoint {
131+ id: point1
132+ },
133+ TouchPoint {
134+ id: point2
135+ }
136+ ]
137+ }
138+}
qml/Components/VolumeControl.qml+1−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -28,10 +28,6 @@ Item {
2828 readonly property int stepDown: -1
2929
3030 property var indicators // passed from Shell.qml
31− readonly property bool showNotification: indicators && indicators.fullyOpened && indicators.currentIndicator === "indicator-sound"
32− onShowNotificationChanged: { // disallow the volume notification when using the slider, lpbug#1484126
33− actionGroup.indicatorsAction.updateState(root.showNotification);
34− }
3531
3632 GlobalShortcut {
3733 id: muteShortcut
@@ -47,7 +43,6 @@ Item {
4743
4844 property variant actionObject: action("volume")
4945 property variant muteActionObject: indicators.indicatorsModel.profile === "desktop" ? action("mute") : action("silent-mode")
50− property variant indicatorsAction: action("indicator-shown")
5146 }
5247
5348 function volumeUp() {
qml/Components/ZoomableImage.qml+1−1
@@ -65,7 +65,7 @@ Item {
6565 anchors.fill: parent
6666 fillMode: Image.PreserveAspectFit
6767
68− readonly property int sourceSizeMultiplier: 3
68+ readonly property int sourceSizeMultiplier: root.zoomable ? 3 : 1
6969
7070 sourceSize.width: root.width * sourceSizeMultiplier <= root.height * sourceSizeMultiplier ? root.width * sourceSizeMultiplier : 0
7171 sourceSize.height: root.height * sourceSizeMultiplier <= root.width * sourceSizeMultiplier ? root.height * sourceSizeMultiplier : 0
qml/Dash/CardCarousel.qml−1
@@ -64,7 +64,6 @@ DashRenderer {
6464 item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });
6565 item.height = Qt.binding(function() { return cardTool.cardHeight; });
6666 item.cardData = Qt.binding(function() { return model; });
67− item.components = Qt.binding(function() { return cardTool.components; });
6867 item.fontScale = Qt.binding(function() { return carousel.fontScale; });
6968 item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
7069 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
qml/Dash/CardGrid.qml+3−2
@@ -20,12 +20,14 @@ import "../Components"
2020DashRenderer {
2121 id: root
2222
23+ readonly property real defaultMinimumHorizontalSpacing: units.gu(1)
2324 readonly property int collapsedRows: {
2425 if (!cardTool || !cardTool.template || typeof cardTool.template["collapsed-rows"] != "number") return 2;
2526 return cardTool.template["collapsed-rows"];
2627 }
2728 property string artShapeStyle: "inset";
2829 property string backgroundShapeStyle: "inset";
30+ property alias minimumHorizontalSpacing: grid.minimumHorizontalSpacing
2931
3032 expandedHeight: grid.totalContentHeight
3133 collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows, grid.cellHeight), expandedHeight)
@@ -45,7 +47,7 @@ DashRenderer {
4547 ResponsiveGridView {
4648 id: grid
4749 anchors.fill: parent
48− minimumHorizontalSpacing: units.gu(1)
50+ minimumHorizontalSpacing: root.defaultMinimumHorizontalSpacing
4951 delegateWidth: cardTool.cardWidth
5052 delegateHeight: cardTool.cardHeight
5153 verticalSpacing: units.gu(1)
@@ -68,7 +70,6 @@ DashRenderer {
6870 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
6971 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
7072 item.cardData = Qt.binding(function() { return model; });
71− item.components = Qt.binding(function() { return cardTool.components; });
7273 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
7374 item.scopeStyle = root.scopeStyle;
7475 item.artShapeStyle = root.artShapeStyle;
qml/Dash/CardHorizontalList.qml−1
@@ -53,7 +53,6 @@ DashRenderer {
5353 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
5454 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
5555 item.cardData = Qt.binding(function() { return model; });
56− item.components = Qt.binding(function() { return cardTool.components; });
5756 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
5857 item.scopeStyle = root.scopeStyle;
5958 }
qml/Dash/CardTool.qml−1
@@ -220,7 +220,6 @@ Item {
220220 onLoaded: {
221221 item.objectName = "cardToolCard";
222222 item.asynchronous = false;
223− item.components = Qt.binding(function() { return cardTool.components; });
224223 item.width = Qt.binding(function() { return cardTool.cardWidth !== -1 ? cardTool.cardWidth : item.implicitWidth; });
225224 item.height = Qt.binding(function() { return cardTool.cardHeight !== -1 ? cardTool.cardHeight : item.implicitHeight; });
226225 }
qml/Dash/CardVerticalJournal.qml−1
@@ -72,7 +72,6 @@ DashRenderer {
7272 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
7373 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
7474 item.cardData = Qt.binding(function() { return model; });
75− item.components = Qt.binding(function() { return cardTool.components; });
7675 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
7776 item.scopeStyle = root.scopeStyle;
7877 }
qml/Dash/DashBackground.qml+6−2
@@ -15,12 +15,16 @@
1515 */
1616
1717import QtQuick 2.4
18+import QtQuick.Window 2.2
19+import Ubuntu.Thumbnailer 0.1
1820
1921Image {
20− source: anchors.fill.width > anchors.fill.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png"
22+ source: "image://thumbnailer/" + Qt.resolvedUrl("graphics/paper.png")
2123 fillMode: Image.PreserveAspectCrop
2224 horizontalAlignment: Image.AlignRight
2325 verticalAlignment: Image.AlignTop
24− sourceSize.width: anchors.fill.width
26+ // avoid CPU scaling when window size changes
27+ readonly property int maxSize: Math.max(Screen.width, Screen.height)
28+ sourceSize.width: maxSize
2529 sourceSize.height: 0
2630}
qml/Dash/DashPageHeader.qml+1
@@ -102,6 +102,7 @@ Item {
102102 "edgeMargins": units.gu(1)
103103 }
104104 );
105+ searchTextField.forceActiveFocus();
105106 }
106107 }
107108
qml/Dash/GenericScopeView.qml+20−9
@@ -360,17 +360,10 @@ FocusScope {
360360 baseItem.expand(shouldExpand, false /*animate*/);
361361 }
362362 updateRanges();
363+ clickScopeSizingHacks();
363364 if (scope && scope.id === "clickscope") {
364365 if (categoryId === "predefined" || categoryId === "local") {
365− // Yeah, hackish :/
366− if (scopeView.width > units.gu(45)) {
367− if (scopeView.width >= units.gu(70)) {
368− cardTool.cardWidth = units.gu(9);
369− } else {
370− cardTool.cardWidth = units.gu(10);
371− }
372− }
373− cardTool.artShapeSize = Qt.size(units.gu(8), units.gu(7.5));
366+ cardTool.artShapeSize = Qt.binding(function() { return Qt.size(units.gu(8), units.gu(7.5)) });
374367 item.artShapeStyle = "icon";
375368 } else {
376369 // Should be ubuntu store icon
@@ -387,6 +380,23 @@ FocusScope {
387380 }
388381 }
389382
383+ function clickScopeSizingHacks() {
384+ if (scope && scope.id === "clickscope" &&
385+ (categoryId === "predefined" || categoryId === "local")) {
386+ // Yeah, hackish :/
387+ if (scopeView.width > units.gu(45)) {
388+ if (scopeView.width >= units.gu(70)) {
389+ cardTool.cardWidth = units.gu(11);
390+ item.minimumHorizontalSpacing = units.gu(5);
391+ return;
392+ } else {
393+ cardTool.cardWidth = units.gu(10);
394+ }
395+ }
396+ item.minimumHorizontalSpacing = item.defaultMinimumHorizontalSpacing;
397+ }
398+ }
399+
390400 Connections {
391401 target: rendererLoader.item
392402 onClicked: { // (int index, var result, var item, var itemModel)
@@ -416,6 +426,7 @@ FocusScope {
416426 target: scopeView
417427 onIsCurrentChanged: rendererLoader.updateRanges();
418428 onVisibleToParentChanged: rendererLoader.updateRanges();
429+ onWidthChanged: rendererLoader.clickScopeSizingHacks();
419430 }
420431 Connections {
421432 target: holdingList
qml/Dash/Previews/PreviewAudioPlayback.qml+21−76
@@ -15,8 +15,8 @@
1515 */
1616
1717import QtQuick 2.4
18−import QtMultimedia 5.0
1918import Ubuntu.Components 1.3
19+import Dash 0.1
2020
2121/*! \brief Preview widget for audio tracks.
2222
@@ -36,38 +36,6 @@ PreviewWidget {
3636 id: root
3737 implicitHeight: childrenRect.height
3838
39− onIsCurrentPreviewChanged: if (!isCurrentPreview) audio.stop()
40−
41− Audio {
42− id: audio
43− objectName: "audio"
44−
45− property real progress: audio.position / audio.duration
46− property Item playingItem
47−
48− Component.onDestruction: {
49− // destroying the component doesn't automatically send stop to the media service, probably a bug in QtMultimedia
50− audio.stop();
51− }
52−
53− onErrorStringChanged: console.warn("Audio player error:", errorString)
54−
55− function lengthToString(s) {
56− if (typeof(s) !== "number" || s <= 0) return "";
57−
58− var sec = "" + s % 60;
59− if (sec.length == 1) sec = "0" + sec;
60− var hour = Math.floor(s / 3600);
61− if (hour < 1) {
62− return Math.floor(s / 60) + ":" + sec;
63− } else {
64− var min = "" + Math.floor(s / 60) % 60;
65− if (min.length == 1) min = "0" + min;
66− return hour + ":" + min + ":" + sec;
67− }
68− }
69− }
70−
7139 Column {
7240 anchors { left: parent.left; right: parent.right }
7341 visible: trackRepeater.count > 0
@@ -77,20 +45,12 @@ PreviewWidget {
7745 objectName: "trackRepeater"
7846 model: root.widgetData["tracks"]
7947
80− function play(item, source) {
81− audio.stop();
82− // Make sure we change the source, even if two items point to the same uri location
83− audio.source = "";
84− audio.source = source;
85− audio.playingItem = item;
86− audio.play();
87− }
88−
8948 delegate: Item {
9049 id: trackItem
9150 objectName: "trackItem" + index
9251
93− property bool isPlayingItem: audio.playingItem == trackItem
52+ readonly property url sourceUrl: modelData["source"]
53+ readonly property bool isPlayingItem: AudioUrlComparer.compare(sourceUrl, DashAudioPlayer.currentSource)
9454
9555 anchors { left: parent.left; right: parent.right }
9656 height: units.gu(5)
@@ -98,9 +58,9 @@ PreviewWidget {
9858 Row {
9959 id: trackRow
10060
101− property int column1Width: units.gu(3)
102− property int column2Width: width - (2 * spacing) - column1Width - column3Width
103− property int column3Width: units.gu(4)
61+ readonly property int column1Width: units.gu(3)
62+ readonly property int column2Width: width - (2 * spacing) - column1Width - column3Width
63+ readonly property int column3Width: units.gu(4)
10464
10565 anchors.verticalCenter: parent.verticalCenter
10666 width: parent.width
@@ -110,7 +70,8 @@ PreviewWidget {
11070 objectName: "playButton"
11171 width: trackRow.column1Width
11272 height: width
113− iconSource: audio.playbackState == Audio.PlayingState && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
73+ iconSource: DashAudioPlayer.playing && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
74+ activeFocusOnPress: false
11475
11576 // Can't be "transparent" or "#00xxxxxx" as the button optimizes away the surrounding shape
11677 // FIXME when this is resolved: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1251685
@@ -118,13 +79,17 @@ PreviewWidget {
11879
11980 onClicked: {
12081 if (trackItem.isPlayingItem) {
121− if (audio.playbackState == Audio.PlayingState) {
122− audio.pause();
123− } else if (audio.playbackState == Audio.PausedState) {
124− audio.play();
82+ if (DashAudioPlayer.playing) {
83+ DashAudioPlayer.pause();
84+ } else if (DashAudioPlayer.paused) {
85+ DashAudioPlayer.play();
12586 }
12687 } else {
127− trackRepeater.play(trackItem, modelData["source"]);
88+ var playlist = [];
89+ for (var i = 0; i < trackRepeater.count; ++i) {
90+ playlist.push(trackRepeater.itemAt(i).sourceUrl);
91+ }
92+ DashAudioPlayer.playSource(sourceUrl, playlist);
12893 }
12994 }
13095 }
@@ -160,30 +125,10 @@ PreviewWidget {
160125 elide: Text.ElideRight
161126 }
162127
163− UbuntuShape {
164− id: progressBarFill
165− objectName: "progressBarFill"
166−
167− property int maxWidth: progressBarImage.width - units.dp(4)
168−
169− anchors {
170− left: progressBarImage.left
171− right: progressBarImage.right
172− verticalCenter: progressBarImage.verticalCenter
173− margins: units.dp(2)
174− rightMargin: maxWidth - (maxWidth * audio.progress) + units.dp(2)
175− }
176− height: units.dp(2)
177− visible: progressBarImage.visible
178− backgroundColor: UbuntuColors.orange
179− }
180−
181− Image {
182− id: progressBarImage
128+ AudioProgressBar {
183129 anchors { left: parent.left; top: parent.bottom; right: parent.right }
184− height: units.dp(6)
185− visible: audio.playbackState != Audio.StoppedState && trackItem.isPlayingItem && modelData["length"] > 0
186− source: "graphics/music_progress_bg.png"
130+ visible: !DashAudioPlayer.stopped && trackItem.isPlayingItem && modelData["length"] > 0
131+ source: sourceUrl
187132 }
188133 }
189134
@@ -196,7 +141,7 @@ PreviewWidget {
196141 color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
197142 fontSize: "small"
198143 horizontalAlignment: Text.AlignRight
199− text: audio.lengthToString(modelData["length"])
144+ text: DashAudioPlayer.lengthToString(modelData["length"])
200145 }
201146 }
202147 }
qml/Dash/Previews/PreviewHeader.qml+1−1
@@ -35,7 +35,7 @@ PreviewWidget {
3535 Item {
3636 id: headerRoot
3737 objectName: "innerPreviewHeader"
38− readonly property url mascot: root.widgetData["mascot"] || ""
38+ readonly property url mascot: root.widgetData["mascot"] || fallback
3939 readonly property url fallback: root.widgetData["fallback"] || ""
4040 readonly property string title: root.widgetData["title"] || ""
4141 readonly property string subtitle: root.widgetData["subtitle"] || ""
qml/Dash/Previews/PreviewImageGallery.qml+2−2
@@ -59,7 +59,7 @@ PreviewWidget {
5959 top: parent.top
6060 bottom: parent.bottom
6161 }
62− source: modelData ? modelData : ""
62+ source: modelData || root.widgetData["fallback"] || ""
6363 scaleTo: "height"
6464 initialWidth: units.gu(13)
6565 pressed: mouseArea.pressed
@@ -128,7 +128,7 @@ PreviewWidget {
128128 bottom: parent.bottom
129129 }
130130 width: overlay.width
131− source: modelData ? modelData : ""
131+ source: modelData || root.widgetData["fallback"] || ""
132132 fillMode: Image.PreserveAspectFit
133133 sourceSize { width: screenshot.width; height: screenshot.height }
134134
qml/Dash/Previews/PreviewMediaToolbar.qml+2−1
@@ -23,10 +23,11 @@ Rectangle {
2323
2424 implicitHeight: units.gu(6)
2525 color: Qt.rgba(0, 0, 0, 0.8)
26− visible: sharingWidget.visible
26+ visible: sharingWidget.active
2727
2828 PreviewSharing {
2929 id: sharingWidget
30+ objectName: "sharingWidget"
3031 anchors {
3132 left: parent.left
3233 verticalCenter: parent.verticalCenter
qml/Dash/Previews/PreviewRatingEdit.qml+1
@@ -75,6 +75,7 @@ PreviewWidget {
7575 reviewText: widgetData["review"]
7676
7777 onTriggered: root.triggered(widgetId, actionId, data);
78+ onMakeSureVisible: root.makeSureVisible(item);
7879 }
7980
8081}
qml/Dash/Previews/PreviewSharing.qml+3−4
@@ -24,13 +24,12 @@ Item {
2424 implicitWidth: button.width
2525
2626 property var shareData
27+ property alias active: peerPicker.active
2728 readonly property bool isUrlExternal: url && url.indexOf("file:///") != 0 && url.indexOf("/") != 0
28− readonly property string contentType: shareData ? shareData["contentType"] : ""
29+ readonly property string contentType: shareData ? shareData["content-type"] : ""
2930 readonly property var url: shareData ? shareData["uri"] : ""
3031 readonly property Item rootItem: QuickUtils.rootItem(root)
3132
32− visible: url != ""
33−
3433 AbstractButton {
3534 id: button
3635 height: units.gu(4)
@@ -98,7 +97,7 @@ Item {
9897 parent: rootItem
9998 anchors.fill: parent
10099 visible: false
101− active: root.visible
100+ active: root.url != ""
102101
103102 sourceComponent: contentPeerComponent
104103 }
qml/Dash/Previews/PreviewVideoPlayback.qml+1−1
@@ -81,7 +81,7 @@ PreviewWidget {
8181 right: parent.right
8282 bottom: parent.bottom
8383 }
84− shareData: widgetData["shareData"]
84+ shareData: widgetData["share-data"]
8585 }
8686 }
8787}
qml/Dash/Previews/PreviewZoomableImage.qml+3−3
@@ -42,7 +42,7 @@ PreviewWidget {
4242 right: parent.right
4343 }
4444 scaleTo: "width"
45− source: widgetData["source"]
45+ source: widgetData["source"] || widgetData["fallback"] || ""
4646 asynchronous: true
4747 useUbuntuShape: false
4848 pressed: mouseArea.pressed
@@ -72,7 +72,7 @@ PreviewWidget {
7272 right: parent.right
7373 bottom: parent.bottom
7474 }
75− shareData: widgetData["shareData"]
75+ shareData: widgetData["share-data"]
7676 }
7777 }
7878
@@ -86,7 +86,7 @@ PreviewWidget {
8686
8787 delegate: ZoomableImage {
8888 anchors.fill: parent
89− source: widgetData["source"]
89+ source: widgetData["source"] || widgetData["fallback"] || ""
9090 zoomable: widgetData["zoomable"] ? widgetData["zoomable"] : false
9191 // If modelData would change after failing to load it would not be
9292 // reloaded since the source binding is destroyed by the source = fallback
qml/Dash/Previews/graphics/music_progress_bg.pngdeleted

Binary file not shown.

qml/Dash/graphics/paper.pngnew file

Binary file not shown.

qml/Dash/graphics/paper_landscape@27.pngdeleted

Binary file not shown.

qml/Dash/graphics/paper_portrait@27.pngdeleted

Binary file not shown.

qml/DisabledScreenNotice.qml+72−19
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -15,35 +15,88 @@
1515 */
1616
1717import QtQuick 2.4
18+import QtQuick.Layouts 1.1
1819import Ubuntu.Components 1.3
20+import QtQuick.Window 2.2
1921import "Components"
2022
21−Image {
23+Item {
2224 id: root
2325
26+ property bool infoNoteDisplayed: true
27+
2428 WallpaperResolver {
2529 width: root.width
2630 id: wallpaperResolver
2731 }
2832
29− source: wallpaperResolver.background
33+ Item {
34+ id: contentContainer
35+ anchors.centerIn: parent
36+ height: rotation == 90 || rotation == 270 ? parent.width : parent.height
37+ width: rotation == 90 || rotation == 270 ? parent.height : parent.width
3038
31− UbuntuShape {
32− anchors.fill: text
33− anchors.margins: -units.gu(2)
34− backgroundColor: "black"
35− opacity: 0.4
36− }
39+ rotation: {
40+ switch (Screen.orientation) {
41+ case Qt.PortraitOrientation:
42+ return 0;
43+ case Qt.LandscapeOrientation:
44+ return 270;
45+ case Qt.InvertedPortraitOrientation:
46+ return 180;
47+ case Qt.InvertedLandscapeOrientation:
48+ return 90;
49+ }
50+ }
51+ transformOrigin: Item.Center
3752
38− Label {
39− id: text
40− anchors.centerIn: parent
41− width: parent.width / 2
42− text: i18n.tr("Your device is now connected to an external display.")
43− color: "white"
44− horizontalAlignment: Text.AlignHCenter
45− verticalAlignment: Text.AlignVCenter
46− fontSize: "x-large"
47− wrapMode: Text.Wrap
53+ VirtualTouchPad {
54+ anchors.fill: parent
55+
56+ onPressedChanged: {
57+ if (pressed && infoNoteDisplayed) {
58+ infoNoteDisplayed = false;
59+ }
60+ }
61+ }
62+
63+ Image {
64+ anchors.fill: parent
65+ source: wallpaperResolver.background
66+ }
67+
68+ Item {
69+ objectName: "infoNoticeArea"
70+ anchors.fill: parent
71+ opacity: infoNoteDisplayed ? 1 : 0
72+ visible: opacity > 0
73+ Behavior on opacity {
74+ UbuntuNumberAnimation { }
75+ }
76+
77+ Rectangle {
78+ anchors.fill: parent
79+ color: "black"
80+ opacity: 0.4
81+ }
82+
83+ Label {
84+ id: text
85+ anchors.centerIn: parent
86+ width: parent.width - units.gu(8)
87+ text: i18n.tr("Your device is now connected to an external display. Use this screen as a touch pad to interact with the mouse.")
88+ color: "white"
89+ horizontalAlignment: Text.AlignHCenter
90+ verticalAlignment: Text.AlignVCenter
91+ fontSize: "x-large"
92+ wrapMode: Text.Wrap
93+ }
94+ }
95+
96+ InputMethod {
97+ id: inputMethod
98+ objectName: "inputMethod"
99+ anchors.fill: parent
100+ }
48101 }
49102}
qml/Greeter/Greeter.qml+9−5
@@ -34,7 +34,7 @@ Showable {
3434 // How far to offset the top greeter layer during a launcher left-drag
3535 property real launcherOffset
3636
37− readonly property bool active: shown || hasLockedApp
37+ readonly property bool active: required || hasLockedApp
3838 readonly property bool fullyShown: loader.item ? loader.item.fullyShown : false
3939
4040 // True when the greeter is waiting for PAM or other setup process
@@ -226,14 +226,17 @@ Showable {
226226 }
227227
228228 function checkForForcedDelay() {
229+ if (greeterSettings.lockedOutTime === 0) {
230+ return;
231+ }
232+
229233 var now = new Date();
230− delayTarget = now;
231− delayTarget.setTime(greeterSettings.lockedOutTime + failedLoginsDelayMinutes * 60000);
234+ delayTarget = new Date(greeterSettings.lockedOutTime + failedLoginsDelayMinutes * 60000);
232235
233236 // If tooEarly is true, something went very wrong. Bug or NTP
234237 // misconfiguration maybe?
235238 var tooEarly = now.getTime() < greeterSettings.lockedOutTime;
236− var tooLate = now > delayTarget;
239+ var tooLate = now >= delayTarget;
237240
238241 // Compare stored time to system time. If a malicious actor is
239242 // able to manipulate time to avoid our lockout, they already have
@@ -275,6 +278,7 @@ Showable {
275278 onSelected: {
276279 d.selectUser(index, true);
277280 }
281+ onPromptlessLogin: d.login();
278282 onResponded: {
279283 if (root.locked) {
280284 LightDMService.greeter.respond(response);
@@ -397,8 +401,8 @@ Showable {
397401
398402 if (LightDMService.greeter.authenticated) {
399403 AccountsService.failedLogins = 0;
400− d.login();
401404 if (!LightDMService.greeter.promptless) {
405+ d.login();
402406 loader.item.hide();
403407 }
404408 } else {
qml/Greeter/LoginList.qml+5
@@ -22,6 +22,7 @@ Item {
2222 id: root
2323
2424 property alias model: userList.model
25+ property bool alphanumeric: true
2526 property int currentIndex
2627 property bool locked
2728
@@ -34,6 +35,7 @@ Item {
3435
3536 signal selected(int index)
3637 signal responded(string response)
38+ signal promptlessLogin()
3739
3840 function tryToUnlock() {
3941 if (wasPrompted) {
@@ -42,6 +44,7 @@ Item {
4244 if (root.locked) {
4345 root.selected(currentIndex);
4446 } else {
47+ promptlessLogin();
4548 root.responded("");
4649 }
4750 }
@@ -231,6 +234,8 @@ Item {
231234 width: parent.width - anchors.margins * 2
232235 opacity: userList.movingInternally ? 0 : 1
233236
237+ inputMethodHints: root.alphanumeric ? Qt.ImhNone : Qt.ImhDigitsOnly
238+
234239 property string promptText
235240 placeholderText: root.wasPrompted ? promptText
236241 : (root.locked ? i18n.tr("Retry")
qml/Greeter/WideView.qml+3−1
@@ -27,7 +27,7 @@ FocusScope {
2727 property alias backgroundTopMargin: coverPage.backgroundTopMargin
2828 property alias background: coverPage.background
2929 property bool locked
30− property bool alphanumeric // unused
30+ property alias alphanumeric: loginList.alphanumeric
3131 property alias userModel: loginList.model
3232 property alias infographicModel: coverPage.infographicModel
3333 readonly property bool fullyShown: coverPage.showProgress === 1
@@ -37,6 +37,7 @@ FocusScope {
3737 // so that it can be replaced in tests with a mock object
3838 property var inputMethod: Qt.inputMethod
3939
40+ signal promptlessLogin()
4041 signal selected(int index)
4142 signal responded(string response)
4243 signal tease()
@@ -128,6 +129,7 @@ FocusScope {
128129
129130 locked: root.locked
130131
132+ onPromptlessLogin: root.promptlessLogin()
131133 onSelected: root.selected(index)
132134 onResponded: root.responded(response)
133135 }
qml/Launcher/Launcher.qml+22−28
@@ -51,9 +51,9 @@ Item {
5151
5252 onStateChanged: {
5353 if (state == "") {
54− dismissTimer.stop()
54+ panel.dismissTimer.stop()
5555 } else {
56− dismissTimer.restart()
56+ panel.dismissTimer.restart()
5757 }
5858 }
5959
@@ -96,21 +96,6 @@ Item {
9696 property string mode: "teasing"
9797 }
9898
99− Timer {
100− id: dismissTimer
101− objectName: "dismissTimer"
102− interval: 500
103− onTriggered: {
104− if (root.autohideEnabled) {
105− if (!panel.preventHiding) {
106− root.state = ""
107− } else {
108− dismissTimer.restart()
109− }
110− }
111− }
112− }
113−
11499 // Because the animation on x is disabled while dragging
115100 // switching state directly in the drag handlers would not animate
116101 // the completion of the hide/reveal gesture. Lets update the state
@@ -184,18 +169,13 @@ Item {
184169 }
185170 }
186171
187− MultiPointTouchArea {
172+ InverseMouseArea {
188173 id: closeMouseArea
189− anchors {
190− left: launcherDragArea.right
191− top: parent.top
192− right: parent.right
193− bottom: parent.bottom
194− }
174+ anchors.fill: panel
195175 enabled: root.shadeBackground && root.state == "visible"
196− visible: enabled // otherwise it will get in the way of cursor selection for some reason
176+ visible: enabled
197177 onPressed: {
198− root.state = ""
178+ root.hide();
199179 }
200180 }
201181
@@ -243,6 +223,20 @@ Item {
243223 visible: root.x > 0 || x > -width || dragArea.pressed
244224 model: LauncherModel
245225
226+ property var dismissTimer: Timer { interval: 500 }
227+ Connections {
228+ target: panel.dismissTimer
229+ onTriggered: {
230+ if (root.autohideEnabled) {
231+ if (!panel.preventHiding) {
232+ root.state = ""
233+ } else {
234+ panel.dismissTimer.restart()
235+ }
236+ }
237+ }
238+ }
239+
246240 property bool animate: true
247241
248242 onApplicationSelected: {
@@ -255,8 +249,8 @@ Item {
255249 }
256250
257251 onPreventHidingChanged: {
258− if (dismissTimer.running) {
259− dismissTimer.restart();
252+ if (panel.dismissTimer.running) {
253+ panel.dismissTimer.restart();
260254 }
261255 }
262256
qml/Launcher/LauncherPanel.qml+6−3
@@ -392,7 +392,6 @@ Rectangle {
392392 }
393393
394394 onClicked: {
395− Haptics.play();
396395 var index = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
397396 var clickedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY)
398397
@@ -407,9 +406,11 @@ Rectangle {
407406 quickList.model = launcherListView.model.get(index).quickList;
408407 quickList.appId = launcherListView.model.get(index).appId;
409408 quickList.state = "open";
410− return
409+ return;
411410 }
412411
412+ Haptics.play();
413+
413414 // First/last item do the scrolling at more than 12 degrees
414415 if (index == 0 || index == launcherListView.count - 1) {
415416 if (clickedItem.angle > 12) {
@@ -594,6 +595,7 @@ Rectangle {
594595 width: itemWidth
595596 rotation: root.rotation
596597 itemOpacity: 0.9
598+ onVisibleChanged: if (!visible) iconName = "";
597599
598600 function flatten() {
599601 fakeDragItemAnimation.start();
@@ -636,6 +638,7 @@ Rectangle {
636638 rotation: 90
637639 }
638640 }
641+
639642 InverseMouseArea {
640643 anchors.fill: quickListShape
641644 enabled: quickList.state == "open" || pressed
@@ -692,7 +695,7 @@ Rectangle {
692695 property var item
693696
694697 // internal
695− property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)
698+ property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) + quickList.item.offset : units.gu(1)
696699 property int offset: itemCenter + (height/2) + units.gu(1) > parent.height ? -itemCenter - (height/2) - units.gu(1) + parent.height :
697700 itemCenter - (height/2) < units.gu(1) ? (height/2) - itemCenter + units.gu(1) : 0
698701
qml/OrientedShell.qml+28−14
@@ -18,6 +18,7 @@ import QtQuick 2.4
1818import QtQuick.Window 2.2
1919import Unity.InputInfo 0.1
2020import Unity.Session 0.1
21+import Unity.Screens 0.1
2122import GSettings 1.0
2223import "Components"
2324import "Rotation"
@@ -78,6 +79,15 @@ Rectangle {
7879 deviceFilter: InputInfo.Keyboard
7980 }
8081
82+ InputDeviceModel {
83+ id: touchScreensModel
84+ deviceFilter: InputInfo.TouchScreen
85+ }
86+
87+ Screens {
88+ id: screens
89+ }
90+
8191 property int orientation
8292 onPhysicalOrientationChanged: {
8393 if (!orientationLocked) {
@@ -97,8 +107,7 @@ Rectangle {
97107 }
98108 // We need to manually update this on startup as the binding
99109 // below doesn't seem to have any effect at that stage
100− oskSettings.stayHidden = keyboardsModel.count > 0
101− oskSettings.disableHeight = shell.usageScenario == "desktop"
110+ oskSettings.disableHeight = !shell.oskEnabled || shell.usageScenario == "desktop"
102111 }
103112
104113 // we must rotate to a supported orientation regardless of shell's preference
@@ -106,17 +115,10 @@ Rectangle {
106115 (shell.orientation & supportedOrientations) === 0 ? true
107116 : shell.orientationChangesEnabled
108117
109−
110− Binding {
111− target: oskSettings
112− property: "stayHidden"
113− value: keyboardsModel.count > 0
114− }
115−
116118 Binding {
117119 target: oskSettings
118120 property: "disableHeight"
119− value: shell.usageScenario == "desktop"
121+ value: !shell.oskEnabled || shell.usageScenario == "desktop"
120122 }
121123
122124 readonly property int supportedOrientations: shell.supportedOrientations
@@ -189,6 +191,11 @@ Rectangle {
189191 nativeHeight: root.height
190192 mode: applicationArguments.mode
191193 hasMouse: miceModel.count + touchPadModel.count > 0
194+ // TODO: Factor in if the current screen is a touch screen and if the user wants to
195+ // have multiple keyboards around. For now we only enable one keyboard at a time
196+ // thus hiding it here if there is a physical one around or if we have a second
197+ // screen (the virtual touchpad & osk on the phone) attached.
198+ oskEnabled: keyboardsModel.count === 0 && screens.count === 1
192199
193200 // TODO: Factor in the connected input devices (eg: physical keyboard, mouse, touchscreen),
194201 // what's the output device (eg: big TV, desktop monitor, phone display), etc.
@@ -202,11 +209,18 @@ Rectangle {
202209 return "tablet";
203210 }
204211 } else { // automatic
205− if (miceModel.count + touchPadModel.count > 0) {
206− return "desktop";
207− } else {
208− return deviceConfiguration.category;
212+ var longEdgeWidth = Math.max(root.width, root.height)
213+ if (longEdgeWidth > units.gu(120)) {
214+ if (keyboardsModel.count + miceModel.count + touchPadModel.count > 0) {
215+ return "desktop";
216+ }
217+ } else if (longEdgeWidth > units.gu(90)){
218+ if (miceModel.count + touchPadModel.count > 0) {
219+ return "desktop";
220+ }
209221 }
222+
223+ return deviceConfiguration.category;
210224 }
211225 }
212226
qml/Panel/IndicatorItem.qml+57−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013-2014 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -17,6 +17,7 @@
1717import QtQuick 2.4
1818import Ubuntu.Components 1.3
1919import Ubuntu.Settings.Components 0.1
20+import QMenuModel 0.1
2021import "Indicators"
2122
2223IndicatorDelegate {
@@ -36,13 +37,24 @@ IndicatorDelegate {
3637 return "#ffffff";
3738 }
3839
39− signal clicked()
40−
4140 implicitWidth: mainItems.width
4241
4342 MouseArea {
43+ readonly property int stepUp: 1
44+ readonly property int stepDown: -1
45+
4446 anchors.fill: parent
45− onClicked: parent.clicked()
47+ acceptedButtons: Qt.MiddleButton
48+ onClicked: {
49+ if ((!expanded || selected) && secondaryAction.valid) {
50+ secondaryAction.activate();
51+ }
52+ }
53+ onWheel: {
54+ if ((!expanded || selected) && scrollAction.valid) {
55+ scrollAction.activate(wheel.angleDelta.y > 0 ? stepUp : stepDown);
56+ }
57+ }
4658 }
4759
4860 Item {
@@ -152,9 +164,6 @@ IndicatorDelegate {
152164 }
153165
154166 StateGroup {
155− id: d
156− property bool useFallbackIcon: false
157−
158167 states: [
159168 State {
160169 name: "minimised"
@@ -251,4 +260,45 @@ IndicatorDelegate {
251260 rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : "";
252261 icons = rootActionState.icons;
253262 }
263+
264+ QtObject {
265+ id: d
266+
267+ property bool useFallbackIcon: false
268+ property var shouldIndicatorBeShown: undefined
269+
270+ onShouldIndicatorBeShownChanged: {
271+ if (shouldIndicatorBeShown !== undefined) {
272+ submenuAction.changeState(shouldIndicatorBeShown);
273+ }
274+ }
275+ }
276+
277+ UnityMenuAction {
278+ id: secondaryAction
279+ model: menuModel
280+ index: 0
281+ name: rootActionState.secondaryAction
282+ }
283+
284+ UnityMenuAction {
285+ id: scrollAction
286+ model: menuModel
287+ index: 0
288+ name: rootActionState.scrollAction
289+ }
290+
291+ UnityMenuAction {
292+ id: submenuAction
293+ model: menuModel
294+ index: 0
295+ name: rootActionState.submenuAction
296+ }
297+
298+ Binding {
299+ target: d
300+ property: "shouldIndicatorBeShown"
301+ when: submenuAction.valid
302+ value: root.selected && root.expanded
303+ }
254304}
qml/Panel/Indicators/MenuItemFactory.qml+24−2
@@ -125,10 +125,12 @@ Item {
125125 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
126126 'max-value': 'double',
127127 'min-icon': 'icon',
128− 'max-icon': 'icon'});
128+ 'max-icon': 'icon',
129+ 'x-canonical-sync-action': 'string'});
129130 }
130131
131132 ServerPropertySynchroniser {
133+ id: sliderPropertySync
132134 objectName: "sync"
133135 syncTimeout: Utils.Constants.indicatorValueTimeout
134136 bufferedSyncTimeout: true
@@ -141,6 +143,16 @@ Item {
141143
142144 onSyncTriggered: menuModel.changeState(menuIndex, value)
143145 }
146+
147+ UnityMenuAction {
148+ model: menuModel
149+ index: menuIndex
150+ name: getExtendedProperty(extendedData, "xCanonicalSyncAction", "")
151+ onStateChanged: {
152+ sliderPropertySync.reset();
153+ sliderPropertySync.updateUserValue();
154+ }
155+ }
144156 }
145157 }
146158
@@ -564,7 +576,17 @@ Item {
564576 active: serverChecked
565577 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
566578 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
567− signalStrength: strengthAction.valid ? strengthAction.state : 0
579+ signalStrength: {
580+ if (strengthAction.valid) {
581+ var state = strengthAction.state; // handle both int and uchar
582+ // FIXME remove the special casing when we switch to indicator-network completely
583+ if (typeof state == "string") {
584+ return state.charCodeAt();
585+ }
586+ return state;
587+ }
588+ return 0;
589+ }
568590 highlightWhenPressed: false
569591
570592 onMenuModelChanged: {
qml/Panel/graphics/Battery@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Bluetooth@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Clock@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Location@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Messages@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Network@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Sound@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Sync@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/System@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/Time@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/VerticalDivider@18.pngdeleted

Binary file not shown.

qml/Panel/graphics/handle@12.pngdeleted

Binary file not shown.

qml/Panel/graphics/handle@12.scideleted−5
@@ -1,5 +0,0 @@
1−border.left: 0
2−border.top: 1
3−border.bottom: 0
4−border.right: 0
5−source: handle@12.png
qml/Panel/graphics/search@12.pngdeleted

Binary file not shown.

qml/Panel/graphics/time_and_date@18.pngdeleted

Binary file not shown.

qml/Shell.qml+15−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@ Item {
5656 property bool beingResized
5757 property string usageScenario: "phone" // supported values: "phone", "tablet" or "desktop"
5858 property string mode: "full-greeter"
59− property bool cursorVisible: false
59+ property alias oskEnabled: inputMethod.enabled
6060 function updateFocusedAppOrientation() {
6161 applicationsDisplayLoader.item.updateFocusedAppOrientation();
6262 }
@@ -84,8 +84,8 @@ Item {
8484 return Qt.PrimaryOrientation;
8585 } else if (greeter && greeter.shown) {
8686 return Qt.PrimaryOrientation;
87− } else if (mainApp) {
88− return shell.orientations.map(mainApp.supportedOrientations);
87+ } else if (applicationsDisplayLoader.item) {
88+ return shell.orientations.map(applicationsDisplayLoader.item.supportedOrientations);
8989 } else {
9090 // we just don't care
9191 return Qt.PortraitOrientation
@@ -175,8 +175,15 @@ Item {
175175 Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
176176 }
177177
178− HomeKeyWatcher {
179− onActivated: { launcher.fadeOut(); shell.showHome(); }
178+ WindowInputMonitor {
179+ onHomeKeyActivated: { launcher.fadeOut(); shell.showHome(); }
180+ onTouchBegun: { cursor.opacity = 0; }
181+ onTouchEnded: {
182+ // move the (hidden) cursor to the last known touch position
183+ var mappedCoords = mapFromItem(null, pos.x, pos.y);
184+ cursor.x = mappedCoords.x;
185+ cursor.y = mappedCoords.y;
186+ }
180187 }
181188
182189 Item {
@@ -676,6 +683,8 @@ Item {
676683 applicationsDisplayLoader.item.pushRightEdge(amount);
677684 }
678685 }
686+
687+ onMouseMoved: { cursor.opacity = 1; }
679688 }
680689
681690 Rectangle {
qml/Stages/AbstractStage.qml+5−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -44,6 +44,10 @@ Rectangle {
4444 property var mainApp: null
4545 property int mainAppWindowOrientationAngle
4646 property bool orientationChangesEnabled
47+ property int supportedOrientations: Qt.PortraitOrientation
48+ | Qt.LandscapeOrientation
49+ | Qt.InvertedPortraitOrientation
50+ | Qt.InvertedLandscapeOrientation
4751
4852 // Shared code for use in stage implementations
4953 GSettings {
qml/Stages/ApplicationWindow.qml+14−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014-2015 Canonical Ltd.
2+ * Copyright 2014-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -37,6 +37,13 @@ FocusScope {
3737 property int requestedWidth: -1
3838 property int requestedHeight: -1
3939
40+ readonly property int minimumWidth: sessionContainer.surface ? sessionContainer.surface.minimumWidth : 0
41+ readonly property int minimumHeight: sessionContainer.surface ? sessionContainer.surface.minimumHeight : 0
42+ readonly property int maximumWidth: sessionContainer.surface ? sessionContainer.surface.maximumWidth : 0
43+ readonly property int maximumHeight: sessionContainer.surface ? sessionContainer.surface.maximumHeight : 0
44+ readonly property int widthIncrement: sessionContainer.surface ? sessionContainer.surface.widthIncrement : 0
45+ readonly property int heightIncrement: sessionContainer.surface ? sessionContainer.surface.heightIncrement : 0
46+
4047 QtObject {
4148 id: d
4249
@@ -82,6 +89,12 @@ FocusScope {
8289 property bool surfaceOldEnoughToBeResized: false
8390 }
8491
92+ Binding {
93+ target: root.application
94+ property: "initialSurfaceSize"
95+ value: Qt.size(root.requestedWidth, root.requestedHeight)
96+ }
97+
8598 Timer {
8699 id: surfaceInitTimer
87100 interval: 100
qml/Stages/DecoratedWindow.qml+7
@@ -39,6 +39,13 @@ FocusScope {
3939 property alias requestedWidth: applicationWindow.requestedWidth
4040 property real requestedHeight
4141
42+ property alias minimumWidth: applicationWindow.minimumWidth
43+ readonly property int minimumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.minimumHeight
44+ property alias maximumWidth: applicationWindow.maximumWidth
45+ readonly property int maximumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.maximumHeight
46+ property alias widthIncrement: applicationWindow.widthIncrement
47+ property alias heightIncrement: applicationWindow.heightIncrement
48+
4249 signal close()
4350 signal maximize()
4451 signal minimize()
qml/Stages/DesktopStage.qml+19−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,11 @@ AbstractStage {
4040 ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
4141 : null
4242
43+ // application windows never rotate independently
44+ mainAppWindowOrientationAngle: shellOrientationAngle
45+
46+ orientationChangesEnabled: true
47+
4348 Connections {
4449 target: ApplicationManager
4550 onApplicationAdded: {
@@ -124,16 +129,20 @@ AbstractStage {
124129 onFocusedAppDelegateChanged: updateForegroundMaximizedApp();
125130
126131 property int foregroundMaximizedAppZ: -1
132+ property int foregroundMaximizedAppIndex: -1 // for stuff like drop shadow and focusing maximized app by clicking panel
127133
128134 function updateForegroundMaximizedApp() {
129135 var tmp = -1;
136+ var tmpAppId = -1;
130137 for (var i = appRepeater.count - 1; i >= 0; i--) {
131138 var item = appRepeater.itemAt(i);
132139 if (item && item.visuallyMaximized) {
140+ tmpAppId = i;
133141 tmp = Math.max(tmp, item.normalZ);
134142 }
135143 }
136144 foregroundMaximizedAppZ = tmp;
145+ foregroundMaximizedAppIndex = tmpAppId;
137146 }
138147
139148 function indexOf(appId) {
@@ -176,8 +185,8 @@ AbstractStage {
176185 onMinimize: priv.focusedAppDelegate && priv.focusedAppDelegate.minimize();
177186 onMaximize: priv.focusedAppDelegate // don't restore minimized apps when double clicking the panel
178187 && priv.focusedAppDelegate.restoreFromMaximized();
179− onFocusMaximizedApp: if (priv.foregroundMaximizedAppIdIndex != -1) {
180− ApplicationManager.focusApplication(appRepeater.itemAt(priv.foregroundMaximizedAppIdIndex).appId);
188+ onFocusMaximizedApp: if (priv.foregroundMaximizedAppIndex != -1) {
189+ ApplicationManager.focusApplication(appRepeater.itemAt(priv.foregroundMaximizedAppIndex).appId);
181190 }
182191 }
183192
@@ -206,7 +215,7 @@ AbstractStage {
206215 Binding {
207216 target: PanelState
208217 property: "dropShadow"
209− value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppIdIndex !== -1
218+ value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppIndex !== -1
210219 }
211220
212221 Component.onDestruction: {
@@ -247,6 +256,12 @@ AbstractStage {
247256 height: decoratedWindow.height
248257 property alias requestedWidth: decoratedWindow.requestedWidth
249258 property alias requestedHeight: decoratedWindow.requestedHeight
259+ property alias minimumWidth: decoratedWindow.minimumWidth
260+ property alias minimumHeight: decoratedWindow.minimumHeight
261+ property alias maximumWidth: decoratedWindow.maximumWidth
262+ property alias maximumHeight: decoratedWindow.maximumHeight
263+ property alias widthIncrement: decoratedWindow.widthIncrement
264+ property alias heightIncrement: decoratedWindow.heightIncrement
250265
251266 QtObject {
252267 id: appDelegatePrivate
qml/Stages/PhoneStage.qml+5−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -83,6 +83,10 @@ AbstractStage {
8383 && !(priv.focusedAppDelegate && priv.focusedAppDelegate.xBehavior.running)
8484 && spreadView.phase === 0
8585
86+ supportedOrientations: mainApp ? mainApp.supportedOrientations
87+ : (Qt.PortraitOrientation | Qt.LandscapeOrientation
88+ | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation)
89+
8690 // How far left the stage has been dragged
8791 readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
8892
qml/Stages/SessionContainer.qml+2
@@ -152,6 +152,8 @@ FocusScope {
152152 popped.completed.connect(function() { root.session.release(); } );
153153 popped.end();
154154 d.animations = tmp;
155+ } else {
156+ root.session.release();
155157 }
156158 }
157159
qml/Stages/Splash.qml+7−2
@@ -138,15 +138,20 @@ Item {
138138 visible: d.showIcon
139139 }
140140
141+ Timer {
142+ interval: 2000
143+ onTriggered: spinner.running = true
144+ running: true
145+ }
146+
141147 ActivityIndicator {
148+ id: spinner
142149 anchors.centerIn: header.visible ? parent : undefined
143150 anchors.verticalCenterOffset: header.visible ? header.height / 2 : 0
144151
145152 anchors.horizontalCenter: header.visible ? undefined : parent.horizontalCenter
146153 anchors.bottom: header.visible ? undefined : parent.bottom
147154 anchors.bottomMargin: header.visible ? 0 : units.gu(12)
148−
149− running: true
150155 }
151156
152157 MouseArea {
qml/Stages/TabletStage.qml+5−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -72,6 +72,10 @@ AbstractStage {
7272
7373 orientationChangesEnabled: priv.mainAppOrientationChangesEnabled
7474
75+ supportedOrientations: mainApp ? mainApp.supportedOrientations
76+ : (Qt.PortraitOrientation | Qt.LandscapeOrientation
77+ | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation)
78+
7579 onWidthChanged: {
7680 spreadView.selectedIndex = -1;
7781 spreadView.phase = 0;
qml/Stages/WindowResizeArea.qml+95−16
@@ -72,8 +72,8 @@ MouseArea {
7272 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
7373 Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
7474
75− target.requestedWidth = Math.min(Math.max(windowGeometry.width, minWidth), screenWidth);
76− target.requestedHeight = Math.min(Math.max(windowGeometry.height, minHeight), root.screenHeight - PanelState.panelHeight);
75+ target.requestedWidth = Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth);
76+ target.requestedHeight = Math.min(Math.max(windowGeometry.height, d.minimumHeight), root.screenHeight - PanelState.panelHeight);
7777 target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0)
7878 target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight)
7979
@@ -91,6 +91,65 @@ MouseArea {
9191
9292 QtObject {
9393 id: d
94+
95+ readonly property int maxSafeInt: 2147483647
96+ readonly property int maxSizeIncrement: units.gu(40)
97+
98+ readonly property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth
99+ onMinimumWidthChanged: {
100+ if (target.requestedWidth < minimumWidth) {
101+ target.requestedWidth = minimumWidth;
102+ }
103+ }
104+ readonly property int minimumHeight: root.target ? Math.max(root.minHeight, root.target.minimumHeight) : root.minHeight
105+ onMinimumHeightChanged: {
106+ if (target.requestedHeight < minimumHeight) {
107+ target.requestedHeight = minimumHeight;
108+ }
109+ }
110+ readonly property int maximumWidth: root.target && root.target.maximumWidth >= minimumWidth && root.target.maximumWidth > 0
111+ ? root.target.maximumWidth : maxSafeInt
112+ onMaximumWidthChanged: {
113+ if (target.requestedWidth > maximumWidth) {
114+ target.requestedWidth = maximumWidth;
115+ }
116+ }
117+ readonly property int maximumHeight: root.target && root.target.maximumHeight >= minimumHeight && root.target.maximumHeight > 0
118+ ? root.target.maximumHeight : maxSafeInt
119+ onMaximumHeightChanged: {
120+ if (target.requestedHeight > maximumHeight) {
121+ target.requestedHeight = maximumHeight;
122+ }
123+ }
124+ readonly property int widthIncrement: {
125+ if (!root.target) {
126+ return 1;
127+ }
128+ if (root.target.widthIncrement > 0) {
129+ if (root.target.widthIncrement < maxSizeIncrement) {
130+ return root.target.widthIncrement;
131+ } else {
132+ return maxSizeIncrement;
133+ }
134+ } else {
135+ return 1;
136+ }
137+ }
138+ readonly property int heightIncrement: {
139+ if (!root.target) {
140+ return 1;
141+ }
142+ if (root.target.heightIncrement > 0) {
143+ if (root.target.heightIncrement < maxSizeIncrement) {
144+ return root.target.heightIncrement;
145+ } else {
146+ return maxSizeIncrement;
147+ }
148+ } else {
149+ return 1;
150+ }
151+ }
152+
94153 property bool leftBorder: false
95154 property bool rightBorder: false
96155 property bool topBorder: false
@@ -209,38 +268,58 @@ MouseArea {
209268
210269 var pos = mapToItem(target.parent, mouse.x, mouse.y);
211270
212− var deltaX = pos.x - d.startMousePosX;
213− var deltaY = pos.y - d.startMousePosY;
271+ var deltaX = Math.floor((pos.x - d.startMousePosX) / d.widthIncrement) * d.widthIncrement;
272+ var deltaY = Math.floor((pos.y - d.startMousePosY) / d.heightIncrement) * d.heightIncrement;
214273
215274 if (d.leftBorder) {
216275 var newTargetX = d.startX + deltaX;
217− if (target.x + target.width > newTargetX + minWidth) {
218− target.requestedWidth = target.x + target.width - newTargetX;
276+ var rightBorderX = target.x + target.width;
277+ if (rightBorderX > newTargetX + d.minimumWidth) {
278+ if (rightBorderX < newTargetX + d.maximumWidth) {
279+ target.requestedWidth = rightBorderX - newTargetX;
280+ } else {
281+ target.requestedWidth = d.maximumWidth;
282+ }
219283 } else {
220− target.requestedWidth = minWidth;
284+ target.requestedWidth = d.minimumWidth;
221285 }
222286
223287 } else if (d.rightBorder) {
224− if (d.startWidth + deltaX >= minWidth) {
225− target.requestedWidth = d.startWidth + deltaX;
288+ var newWidth = d.startWidth + deltaX;
289+ if (newWidth > d.minimumWidth) {
290+ if (newWidth < d.maximumWidth) {
291+ target.requestedWidth = newWidth;
292+ } else {
293+ target.requestedWidth = d.maximumWidth;
294+ }
226295 } else {
227− target.requestedWidth = minWidth;
296+ target.requestedWidth = d.minimumWidth;
228297 }
229298 }
230299
231300 if (d.topBorder) {
232301 var newTargetY = d.startY + deltaY;
233− if (target.y + target.height > newTargetY + minHeight) {
234− target.requestedHeight = target.y + target.height - newTargetY;
302+ var bottomBorderY = target.y + target.height;
303+ if (bottomBorderY > newTargetY + d.minimumHeight) {
304+ if (bottomBorderY < newTargetY + d.maximumHeight) {
305+ target.requestedHeight = bottomBorderY - newTargetY;
306+ } else {
307+ target.requestedHeight = d.maximumHeight;
308+ }
235309 } else {
236− target.requestedHeight = minHeight;
310+ target.requestedHeight = d.minimumHeight;
237311 }
238312
239313 } else if (d.bottomBorder) {
240− if (d.startHeight + deltaY >= minHeight) {
241− target.requestedHeight = d.startHeight + deltaY;
314+ var newHeight = d.startHeight + deltaY;
315+ if (newHeight > d.minimumHeight) {
316+ if (newHeight < d.maximumHeight) {
317+ target.requestedHeight = newHeight;
318+ } else {
319+ target.requestedHeight = d.maximumHeight;
320+ }
242321 } else {
243− target.requestedHeight = minHeight;
322+ target.requestedHeight = d.minimumHeight;
244323 }
245324 }
246325 }
qml/Wizard/Pages/10-welcome.qml+1−1
@@ -41,7 +41,7 @@ LocalComponents.Page {
4141 anchors.left: parent.left
4242 anchors.right: parent.right
4343 wrapMode: Text.Wrap
44− text: i18n.tr("Welcome to your Ubuntu phone.")
44+ text: i18n.tr("Welcome to your Ubuntu device.")
4545 }
4646
4747 Label {
qml/Wizard/Pages/30-passwd-type.qml+6−1
@@ -39,6 +39,11 @@ LocalComponents.Page {
3939 title: i18n.tr("Lock security")
4040 forwardButtonSourceComponent: forwardButton
4141
42+ // If the user has set a password some other way (via ubuntu-device-flash
43+ // or this isn't the first time the wizard has been run, etc). We can't
44+ // properly set the password again, so let's not pretend we can.
45+ skip: securityPrivacy.securityType !== UbuntuSecurityPrivacyPanel.Swipe
46+
4247 function indexToMethod(index) {
4348 if (index === 0)
4449 return UbuntuSecurityPrivacyPanel.Swipe
@@ -71,7 +76,7 @@ LocalComponents.Page {
7176 anchors.left: parent.left
7277 anchors.right: parent.right
7378 wrapMode: Text.Wrap
74− text: i18n.tr("Please select how you’d like to unlock your phone.")
79+ text: i18n.tr("Please select how you’d like to unlock your device.")
7580 }
7681
7782 ItemSelector {
qml/Wizard/Pages/80-finished.qml+1−1
@@ -43,7 +43,7 @@ LocalComponents.Page {
4343 anchors.left: parent.left
4444 anchors.right: parent.right
4545 wrapMode: Text.Wrap
46− text: i18n.tr("Your phone is now ready to use.")
46+ text: i18n.tr("Your device is now ready to use.")
4747 }
4848 }
4949
src/CMakeLists.txt+13−7
@@ -16,10 +16,9 @@ file(GLOB_RECURSE QML_FILES
1616 ${CMAKE_SOURCE_DIR}/tests/*.svg
1717)
1818
19−add_executable(${SHELL_APP}
19+set(SOURCE_FILES
2020 ApplicationArguments.cpp
2121 main.cpp
22− MouseTouchAdaptor.cpp
2322 CachingNetworkManagerFactory.cpp
2423 SecondaryWindow.cpp
2524 ShellApplication.cpp
@@ -28,15 +27,22 @@ add_executable(${SHELL_APP}
2827 ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
2928)
3029
30+if (ENABLE_TOUCH_EMULATION)
31+ set(SOURCE_FILES ${SOURCE_FILES} MouseTouchAdaptor.cpp)
32+endif()
33+
34+pkg_check_modules(ANDROID_PROPERTIES REQUIRED libandroid-properties)
35+add_executable(${SHELL_APP} ${SOURCE_FILES})
3136qt5_use_modules(${SHELL_APP} Gui Qml Quick Test)
3237
33−pkg_check_modules(NEEDED_LIBS REQUIRED xcb libandroid-properties)
34−if (NOT "${NEEDED_LIBS_INCLUDE_DIRS}" STREQUAL "")
35− set_target_properties(${SHELL_APP} PROPERTIES INCLUDE_DIRECTORIES ${NEEDED_LIBS_INCLUDE_DIRS})
38+if (NOT "${ANDROID_PROPERTIES_INCLUDE_DIRS}" STREQUAL "")
39+ set_target_properties(${SHELL_APP} PROPERTIES INCLUDE_DIRECTORIES ${ANDROID_PROPERTIES_INCLUDE_DIRS})
3640endif()
37−target_link_libraries(${SHELL_APP} ${NEEDED_LIBS_LDFLAGS})
41+target_link_libraries(${SHELL_APP} ${ANDROID_PROPERTIES_LDFLAGS} UbuntuGestures connectivity-qt1)
3842
39−target_link_libraries(${SHELL_APP} UbuntuGestures connectivity-qt1)
43+if (ENABLE_TOUCH_EMULATION)
44+ target_link_libraries(${SHELL_APP} ${MOUSETOUCHADAPTOR_LIBS_LDFLAGS})
45+endif()
4046
4147# For it to find libUbuntuGestures.so
4248set_target_properties(${SHELL_APP} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}")
src/Dash/CMakeLists.txt+8−8
@@ -1,25 +1,25 @@
11set(DASH_SRCS
22 main.cpp
3− ../ApplicationArguments.cpp
4− ../MouseTouchAdaptor.cpp
53 ../CachingNetworkManagerFactory.cpp
64)
75
6+if (ENABLE_TOUCH_EMULATION)
7+ set(DASH_SRCS ${DASH_SRCS} ../MouseTouchAdaptor.cpp)
8+endif()
9+
810add_executable(unity8-dash ${DASH_SRCS})
911
1012qt5_use_modules(unity8-dash Gui Qml Quick Test)
1113
12−pkg_check_modules(NEEDED_LIBS REQUIRED xcb libandroid-properties)
13−if (NOT "${NEEDED_LIBS_INCLUDE_DIRS}" STREQUAL "")
14− set_target_properties(unity8-dash PROPERTIES INCLUDE_DIRECTORIES ${NEEDED_LIBS_INCLUDE_DIRS})
15−endif()
16−target_link_libraries(unity8-dash ${NEEDED_LIBS_LDFLAGS})
17−
1814# For it to find libUbuntuGestures.so, needed by Ubuntu.Gestures QML module.
1915set_target_properties(unity8-dash PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}")
2016
2117target_link_libraries(unity8-dash UbuntuGestures connectivity-qt1)
2218
19+if (ENABLE_TOUCH_EMULATION)
20+ target_link_libraries(unity8-dash ${MOUSETOUCHADAPTOR_LIBS_LDFLAGS})
21+endif()
22+
2323set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
2424
2525# install binaries
src/Dash/main.cpp+9−5
@@ -27,8 +27,9 @@
2727#include <libintl.h>
2828
2929#include <paths.h>
30−#include "../MouseTouchAdaptor.h"
31−#include "../ApplicationArguments.h"
30+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
31+ #include "../MouseTouchAdaptor.h"
32+#endif
3233#include "../CachingNetworkManagerFactory.h"
3334
3435int main(int argc, const char *argv[])
@@ -57,8 +58,6 @@ int main(int argc, const char *argv[])
5758 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
5859 parser.process(*application);
5960
60− ApplicationArguments qmlArgs;
61−
6261 if (getenv("QT_LOAD_TESTABILITY")) {
6362 QLibrary testLib(QStringLiteral("qttestability"));
6463 if (testLib.load()) {
@@ -92,14 +91,15 @@ int main(int argc, const char *argv[])
9291 }
9392
9493 view->setTitle(QStringLiteral("Scopes"));
95− view->rootContext()->setContextProperty(QStringLiteral("applicationArguments"), &qmlArgs);
9694
95+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
9796 // You will need this if you want to interact with touch-only components using a mouse
9897 // Needed only when manually testing on a desktop.
9998 MouseTouchAdaptor *mouseTouchAdaptor = 0;
10099 if (parser.isSet(mousetouchOption)) {
101100 mouseTouchAdaptor = MouseTouchAdaptor::instance();
102101 }
102+ #endif
103103
104104 QUrl source(::qmlDirectory() + "/Dash/DashApplication.qml");
105105 prependImportPaths(view->engine(), ::overrideImportPaths());
@@ -114,7 +114,11 @@ int main(int argc, const char *argv[])
114114 int result = application->exec();
115115
116116 delete view;
117+
118+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
117119 delete mouseTouchAdaptor;
120+ #endif
121+
118122 delete application;
119123
120124 return result;
src/MouseTouchAdaptor.cpp+180−21
@@ -16,14 +16,56 @@
1616 * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
1717 */
1818
19+
20+/* Some parts of the code were copied from the XCB platform plugin of the Qt Toolkit,
21+ * which is under the following license:
22+ */
23+
24+/****************************************************************************
25+**
26+** Copyright (C) 2015 The Qt Company Ltd.
27+** Contact: http://www.qt.io/licensing/
28+**
29+** This file is part of the .
30+**
31+** $QT_BEGIN_LICENSE:LGPL21$
32+** Commercial License Usage
33+** Licensees holding valid commercial Qt licenses may use this file in
34+** accordance with the commercial license agreement provided with the
35+** Software or, alternatively, in accordance with the terms contained in
36+** a written agreement between you and The Qt Company. For licensing terms
37+** and conditions see http://www.qt.io/terms-conditions. For further
38+** information use the contact form at http://www.qt.io/contact-us.
39+**
40+** GNU Lesser General Public License Usage
41+** Alternatively, this file may be used under the terms of the GNU Lesser
42+** General Public License version 2.1 or version 3 as published by the Free
43+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
44+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
45+** following information to ensure the GNU Lesser General Public License
46+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
47+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
48+**
49+** As a special exception, The Qt Company gives you certain additional
50+** rights. These rights are described in The Qt Company LGPL Exception
51+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
52+**
53+** $QT_END_LICENSE$
54+**
55+****************************************************************************/
56+
1957#include "MouseTouchAdaptor.h"
2058
59+#include <qpa/qplatformnativeinterface.h>
2160#include <qpa/qwindowsysteminterface.h>
2261
2362#include <QCoreApplication>
2463#include <QMouseEvent>
2564#include <QTest>
2665
66+#include <X11/extensions/XInput2.h>
67+#include <X11/extensions/XI2proto.h>
68+
2769using QTest::QTouchEventSequence;
2870
2971namespace {
@@ -49,6 +91,8 @@ MouseTouchAdaptor::MouseTouchAdaptor()
4991 m_touchDevice = new QTouchDevice;
5092 m_touchDevice->setType(QTouchDevice::TouchScreen);
5193 QWindowSystemInterface::registerTouchDevice(m_touchDevice);
94+
95+ fetchXInput2Info();
5296}
5397
5498MouseTouchAdaptor::~MouseTouchAdaptor()
@@ -65,9 +109,114 @@ MouseTouchAdaptor* MouseTouchAdaptor::instance()
65109 return g_instance;
66110}
67111
112+void MouseTouchAdaptor::fetchXInput2Info()
113+{
114+ QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface();
115+ Display *xDisplay = static_cast<Display*>(nativeInterface->nativeResourceForIntegration("Display"));
116+ if (xDisplay && XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
117+ int xiMajor = 2;
118+ m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
119+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
120+ m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
121+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
122+ m_xi2Minor = 0; // for tablet support 2.0 is enough
123+ m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
124+ } else
125+ m_xi2Enabled = true;
126+ } else {
127+ m_xi2Enabled = true;
128+ }
129+ }
130+}
131+
132+// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
133+// - "pad0" became "extension"
134+// - "pad1" and "pad" became "pad0"
135+// New and old version of this struct share the following fields:
136+// NOTE: API might change again in the next release of xcb in which case this comment will
137+// need to be updated to reflect the reality.
138+typedef struct qt_xcb_ge_event_t {
139+ uint8_t response_type;
140+ uint8_t extension;
141+ uint16_t sequence;
142+ uint32_t length;
143+ uint16_t event_type;
144+} qt_xcb_ge_event_t;
145+
146+bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCode)
147+{
148+ qt_xcb_ge_event_t *event = (qt_xcb_ge_event_t *)ev;
149+ // xGenericEvent has "extension" on the second byte, the same is true for xcb_ge_event_t starting from
150+ // the xcb version 1.9.3, prior to that it was called "pad0".
151+ if (event->extension == opCode) {
152+ // xcb event structs contain stuff that wasn't on the wire, the full_sequence field
153+ // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes.
154+ // Move this data back to have the same layout in memory as it was on the wire
155+ // and allow casting, overwriting the full_sequence field.
156+ memmove((char*) event + 32, (char*) event + 36, event->length * 4);
157+ return true;
158+ }
159+ return false;
160+}
161+
162+static inline qreal fixed1616ToReal(FP1616 val)
163+{
164+ return qreal(val) / 0x10000;
165+}
166+
167+bool MouseTouchAdaptor::xi2HandleEvent(xcb_ge_event_t *event)
168+{
169+ if (!xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) {
170+ return false;
171+ }
172+
173+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
174+ xXIDeviceEvent *xiDeviceEvent = 0;
175+
176+ switch (xiEvent->evtype) {
177+ case XI_ButtonPress:
178+ case XI_ButtonRelease:
179+ case XI_Motion:
180+ xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
181+ break;
182+ default:
183+ break;
184+ }
185+
186+ if (!xiDeviceEvent) {
187+ return false;
188+ }
189+
190+ switch (xiDeviceEvent->evtype) {
191+ case XI_ButtonPress:
192+ return handleButtonPress(
193+ static_cast<WId>(xiDeviceEvent->event),
194+ xiDeviceEvent->detail,
195+ fixed1616ToReal(xiDeviceEvent->event_x),
196+ fixed1616ToReal(xiDeviceEvent->event_y));
197+ case XI_ButtonRelease:
198+ return handleButtonRelease(
199+ static_cast<WId>(xiDeviceEvent->event),
200+ xiDeviceEvent->detail,
201+ fixed1616ToReal(xiDeviceEvent->event_x),
202+ fixed1616ToReal(xiDeviceEvent->event_y));
203+ case XI_Motion:
204+ return handleMotionNotify(
205+ static_cast<WId>(xiDeviceEvent->event),
206+ fixed1616ToReal(xiDeviceEvent->event_x),
207+ fixed1616ToReal(xiDeviceEvent->event_y));
208+ return true;
209+ default:
210+ return false;
211+ }
212+}
213+
214+
68215bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
69216 void * message, long * /*result*/)
70217{
218+ static int eventCount = 0;
219+ eventCount++;
71220 if (!m_enabled) {
72221 return false;
73222 }
@@ -81,32 +230,42 @@ bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
81230 xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
82231
83232 switch (xcbEvent->response_type & ~0x80) {
84− case XCB_BUTTON_PRESS:
85− return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
86− break;
87− case XCB_BUTTON_RELEASE:
88− return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
89− break;
90− case XCB_MOTION_NOTIFY:
91− return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
92− break;
233+ case XCB_BUTTON_PRESS: {
234+ auto pressEvent = reinterpret_cast<xcb_button_press_event_t *>(xcbEvent);
235+ return handleButtonPress(static_cast<WId>(pressEvent->event), pressEvent->detail,
236+ pressEvent->event_x, pressEvent->event_y);
237+ }
238+ case XCB_BUTTON_RELEASE: {
239+ auto releaseEvent = reinterpret_cast<xcb_button_release_event_t *>(xcbEvent);
240+ return handleButtonRelease(static_cast<WId>(releaseEvent->event), releaseEvent->detail,
241+ releaseEvent->event_x, releaseEvent->event_y);
242+ }
243+ case XCB_MOTION_NOTIFY: {
244+ auto motionEvent = reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent);
245+ return handleMotionNotify(static_cast<WId>(motionEvent->event), motionEvent->event_x, motionEvent->event_y);
246+ }
247+ case XCB_GE_GENERIC:
248+ if (m_xi2Enabled) {
249+ return xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(xcbEvent));
250+ } else {
251+ return false;
252+ }
93253 default:
94254 return false;
95− break;
96255 };
97256}
98257
99−bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
258+bool MouseTouchAdaptor::handleButtonPress(WId windowId, uint32_t detail, int x, int y)
100259{
101− Qt::MouseButton button = translateMouseButton(pressEvent->detail);
260+ Qt::MouseButton button = translateMouseButton(detail);
102261
103262 // Just eat the event if it wasn't a left mouse press
104263 if (button != Qt::LeftButton)
105264 return true;
106265
107− QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
266+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
108267
109− QPoint windowPos(pressEvent->event_x / targetWindow->devicePixelRatio(), pressEvent->event_y / targetWindow->devicePixelRatio());
268+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
110269
111270 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
112271 false /* autoCommit */);
@@ -117,17 +276,17 @@ bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
117276 return true;
118277}
119278
120−bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
279+bool MouseTouchAdaptor::handleButtonRelease(WId windowId, uint32_t detail, int x, int y)
121280{
122− Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
281+ Qt::MouseButton button = translateMouseButton(detail);
123282
124283 // Just eat the event if it wasn't a left mouse release
125284 if (button != Qt::LeftButton)
126285 return true;
127286
128− QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
287+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
129288
130− QPoint windowPos(releaseEvent->event_x / targetWindow->devicePixelRatio(), releaseEvent->event_y / targetWindow->devicePixelRatio());
289+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
131290
132291 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
133292 false /* autoCommit */);
@@ -138,15 +297,15 @@ bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseE
138297 return true;
139298}
140299
141−bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
300+bool MouseTouchAdaptor::handleMotionNotify(WId windowId, int x, int y)
142301{
143302 if (!m_leftButtonIsPressed) {
144303 return true;
145304 }
146305
147− QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
306+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
148307
149− QPoint windowPos(event->event_x / targetWindow->devicePixelRatio(), event->event_y / targetWindow->devicePixelRatio());
308+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
150309
151310 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
152311 false /* autoCommit */);
src/MouseTouchAdaptor.h+10−3
@@ -21,6 +21,7 @@
2121
2222#include <QtCore/QAbstractNativeEventFilter>
2323#include <QWindow>
24+
2425#include <xcb/xcb.h>
2526
2627class QMouseEvent;
@@ -47,16 +48,22 @@ Q_SIGNALS:
4748
4849private:
4950 MouseTouchAdaptor();
51+ void fetchXInput2Info();
52+ bool xi2HandleEvent(xcb_ge_event_t *event);
5053
51− bool handleButtonPress(xcb_button_press_event_t *pressEvent);
52− bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
53− bool handleMotionNotify(xcb_motion_notify_event_t *event);
54+ bool handleButtonPress(WId windowId, uint32_t detail, int x, int y);
55+ bool handleButtonRelease(WId windowId, uint32_t detail, int x, int y);
56+ bool handleMotionNotify(WId windowId, int x, int y);
5457 QWindow *findQWindowWithXWindowID(WId windowId);
5558
5659 QTouchDevice *m_touchDevice;
5760 bool m_leftButtonIsPressed;
5861
5962 bool m_enabled;
63+
64+ bool m_xi2Enabled{false};
65+ int m_xi2Minor{-1};
66+ int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
6067};
6168
6269#endif // MOUSE_TOUCH_ADAPTOR_H
src/ShellApplication.cpp+10−5
@@ -18,6 +18,7 @@
1818
1919// Qt
2020#include <QLibrary>
21+#include <QProcess>
2122#include <QScreen>
2223
2324#include <libintl.h>
@@ -28,15 +29,10 @@
2829// local
2930#include <paths.h>
3031#include "CachingNetworkManagerFactory.h"
31−#include "MouseTouchAdaptor.h"
3232#include "UnityCommandLineParser.h"
3333
3434ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
3535 : QGuiApplication(argc, argv)
36− , m_shellView(nullptr)
37− , m_secondaryWindow(nullptr)
38− , m_mouseTouchAdaptor(nullptr)
39− , m_qmlEngine(nullptr)
4036{
4137
4238 setApplicationName(QStringLiteral("unity8"));
@@ -89,11 +85,14 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
8985 m_shellView->setFlags(Qt::FramelessWindowHint);
9086 }
9187
88+
89+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
9290 // You will need this if you want to interact with touch-only components using a mouse
9391 // Needed only when manually testing on a desktop.
9492 if (parser.hasMouseToTouch()) {
9593 m_mouseTouchAdaptor = MouseTouchAdaptor::instance();
9694 }
95+ #endif
9796
9897
9998 // Some hard-coded policy for now.
@@ -117,6 +116,10 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
117116 m_shellView->setHeight(primaryScreenSize.height());
118117 m_shellView->setWidth(primaryScreenSize.width());
119118 m_shellView->show();
119+ m_shellView->requestActivate();
120+ if (!QProcess::startDetached("/sbin/initctl emit --no-wait unity8-greeter-started")) {
121+ qDebug() << "Unable to send unity8-greeter-started event to Upstart";
122+ }
120123 } else if (isMirServer || parser.hasFullscreen()) {
121124 m_shellView->showFullScreen();
122125 } else {
@@ -139,8 +142,10 @@ void ShellApplication::destroyResources()
139142 delete m_secondaryWindow;
140143 m_secondaryWindow = nullptr;
141144
145+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
142146 delete m_mouseTouchAdaptor;
143147 m_mouseTouchAdaptor = nullptr;
148+ #endif
144149
145150 delete m_qmlEngine;
146151 m_qmlEngine = nullptr;
src/ShellApplication.h+12−4
@@ -23,7 +23,11 @@
2323#include <QScopedPointer>
2424
2525#include "ApplicationArguments.h"
26+
27+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
2628#include "MouseTouchAdaptor.h"
29+#endif
30+
2731#include "SecondaryWindow.h"
2832#include "ShellView.h"
2933
@@ -46,10 +50,14 @@ private:
4650 void setupQmlEngine(bool isMirServer);
4751 QString m_deviceName;
4852 ApplicationArguments m_qmlArgs;
49− ShellView *m_shellView;
50− SecondaryWindow *m_secondaryWindow;
51− MouseTouchAdaptor *m_mouseTouchAdaptor;
52− QQmlEngine *m_qmlEngine;
53+ ShellView *m_shellView{nullptr};
54+ SecondaryWindow *m_secondaryWindow{nullptr};
55+
56+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
57+ MouseTouchAdaptor *m_mouseTouchAdaptor{nullptr};
58+ #endif
59+
60+ QQmlEngine *m_qmlEngine{nullptr};
5361};
5462
5563#endif // SHELLAPPLICATION_H
src/UnityCommandLineParser.cpp+6
@@ -37,9 +37,11 @@ UnityCommandLineParser::UnityCommandLineParser(const QCoreApplication &app)
3737 QStringLiteral("Run without window borders"));
3838 parser.addOption(framelessOption);
3939
40+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
4041 QCommandLineOption mousetouchOption(QStringLiteral("mousetouch"),
4142 QStringLiteral("Allow the mouse to provide touch input"));
4243 parser.addOption(mousetouchOption);
44+ #endif
4345
4446 QCommandLineOption windowGeometryOption(QStringList() << QStringLiteral("windowgeometry"),
4547 QStringLiteral("Specify the window geometry as [<width>x<height>]"), QStringLiteral("windowgeometry"), QStringLiteral("1"));
@@ -75,7 +77,11 @@ UnityCommandLineParser::UnityCommandLineParser(const QCoreApplication &app)
7577
7678 m_hasTestability = parser.isSet(testabilityOption);
7779 m_hasFrameless = parser.isSet(framelessOption);
80+
81+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
7882 m_hasMouseToTouch = parser.isSet(mousetouchOption);
83+ #endif
84+
7985 m_hasFullscreen = parser.isSet(fullscreenOption);
8086 m_deviceName = parser.value(devicenameOption);
8187 resolveMode(parser, modeOption);
src/UnityCommandLineParser.h+8
@@ -28,7 +28,11 @@ public:
2828 QSize windowGeometry() const { return m_windowGeometry; }
2929 bool hasTestability() const { return m_hasTestability; }
3030 bool hasFrameless() const { return m_hasFrameless; }
31+
32+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
3133 bool hasMouseToTouch() const { return m_hasMouseToTouch; }
34+ #endif
35+
3236 bool hasFullscreen() const { return m_hasFullscreen; }
3337 QString deviceName() const { return m_deviceName; }
3438 QString mode() const { return m_mode; }
@@ -43,7 +47,11 @@ private:
4347 QSize m_windowGeometry;
4448 bool m_hasTestability;
4549 bool m_hasFrameless;
50+
51+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
4652 bool m_hasMouseToTouch;
53+ #endif
54+
4755 bool m_hasFullscreen;
4856 QString m_deviceName;
4957 QString m_mode;
tests/mocks/CMakeLists.txt+1
@@ -43,6 +43,7 @@ add_subdirectory(Unity)
4343add_subdirectory(QtMultimedia)
4444add_subdirectory(Wizard)
4545add_subdirectory(Utils)
46+add_subdirectory(UInput)
4647
4748install(
4849 DIRECTORY data
tests/mocks/Cursor/Cursor.qml+1
@@ -19,4 +19,5 @@ import QtQuick 2.4
1919Item {
2020 signal pushedLeftBoundary(real amount, int buttons)
2121 signal pushedRightBoundary(real amount, int buttons)
22+ signal mouseMoved()
2223}
tests/mocks/QtMultimedia/CMakeLists.txt+1
@@ -1,6 +1,7 @@
11add_library(QtMultimedia-qml MODULE
22 plugin.cpp
33 audio.cpp
4+ declarativeplaylist.cpp
45 )
56
67qt5_use_modules(QtMultimedia-qml Qml)
tests/mocks/QtMultimedia/audio.cpp+21−19
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -20,30 +20,18 @@
2020
2121Audio::Audio(QObject* parent):
2222 QObject(parent),
23− m_playbackState(StoppedState)
23+ m_playbackState(StoppedState),
24+ m_playlist(0)
2425{
2526 qsrand(time(nullptr));
2627 m_timer.setInterval(1000);
2728 connect(&m_timer, &QTimer::timeout, this, &Audio::timerEvent);
28−}
29−
30−QUrl Audio::source() const
31−{
32− return m_source;
33−}
3429
35−void Audio::setSource(const QUrl &source)
36−{
37− if (m_source != source) {
38− m_source = source;
39− Q_EMIT sourceChanged(source);
40−
41− m_position = 0;
42− Q_EMIT positionChanged(m_position);
30+ m_position = 0;
31+ Q_EMIT positionChanged(m_position);
4332
44− m_duration = (qrand() % 20000) + 10000;
45− Q_EMIT durationChanged(m_duration);
46− }
33+ m_duration = (qrand() % 20000) + 10000;
34+ Q_EMIT durationChanged(m_duration);
4735}
4836
4937Audio::PlaybackState Audio::playbackState() const
@@ -115,3 +103,17 @@ void Audio::setAudioRole(Audio::AudioRole audioRole)
115103{
116104 Q_UNUSED(audioRole);
117105}
106+
107+DeclarativePlaylist *Audio::playlist() const
108+{
109+ return m_playlist;
110+}
111+
112+void Audio::setPlaylist(DeclarativePlaylist *playlist)
113+{
114+ if (playlist == m_playlist)
115+ return;
116+
117+ m_playlist = playlist;
118+ Q_EMIT playlistChanged();
119+}
tests/mocks/QtMultimedia/audio.h+8−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2012,2013 Canonical, Ltd.
2+ * Copyright (C) 2012, 2013, 2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -13,7 +13,6 @@
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 *
16− * Authors: Michael Zanetti <michael.zanetti@canonical.com>
1716 */
1817
1918#ifndef MOCK_AUDIO_H
@@ -23,17 +22,19 @@
2322#include <QUrl>
2423#include <QTimer>
2524
25+class DeclarativePlaylist;
26+
2627class Audio: public QObject
2728{
2829 Q_OBJECT
2930 Q_ENUMS(PlaybackState)
3031 Q_ENUMS(AudioRole)
31− Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
3232 Q_PROPERTY(PlaybackState playbackState READ playbackState NOTIFY playbackStateChanged)
3333 Q_PROPERTY(int position READ position NOTIFY positionChanged)
3434 Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
3535 Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged)
3636 Q_PROPERTY(AudioRole audioRole READ audioRole WRITE setAudioRole)
37+ Q_PROPERTY(DeclarativePlaylist *playlist READ playlist WRITE setPlaylist NOTIFY playlistChanged)
3738public:
3839 enum PlaybackState {
3940 PlayingState,
@@ -50,8 +51,8 @@ public:
5051
5152 explicit Audio(QObject *parent = 0);
5253
53− QUrl source() const;
54− void setSource(const QUrl &source);
54+ DeclarativePlaylist *playlist() const;
55+ void setPlaylist(DeclarativePlaylist *playlist);
5556
5657 PlaybackState playbackState() const;
5758
@@ -70,6 +71,7 @@ public Q_SLOTS:
7071 void stop();
7172
7273Q_SIGNALS:
74+ void playlistChanged();
7375 void sourceChanged(const QUrl &source);
7476 void playbackStateChanged(PlaybackState playbackState);
7577 void positionChanged(int position);
@@ -80,11 +82,11 @@ private Q_SLOTS:
8082 void timerEvent();
8183
8284private:
83− QUrl m_source;
8485 PlaybackState m_playbackState;
8586 QTimer m_timer;
8687 int m_position;
8788 int m_duration;
89+ DeclarativePlaylist *m_playlist;
8890};
8991
9092#endif
tests/mocks/QtMultimedia/declarativeplaylist.cppnew file+73
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include "declarativeplaylist.h"
19+
20+DeclarativePlaylist::DeclarativePlaylist(QObject *parent)
21+ : QObject(parent)
22+ , m_currentIndex(-1)
23+{
24+}
25+
26+QUrl DeclarativePlaylist::currentItemSource() const
27+{
28+ return itemSource(currentIndex());
29+}
30+
31+int DeclarativePlaylist::currentIndex() const
32+{
33+ return m_currentIndex;
34+}
35+
36+void DeclarativePlaylist::setCurrentIndex(int index)
37+{
38+ if (currentIndex() == index)
39+ return;
40+
41+ m_currentIndex = index;
42+ Q_EMIT currentIndexChanged();
43+ Q_EMIT currentItemSourceChanged();
44+}
45+
46+QUrl DeclarativePlaylist::itemSource(int index) const
47+{
48+ if (index < 0 || index >= m_medias.count())
49+ return QUrl();
50+ return m_medias[index];
51+}
52+
53+bool DeclarativePlaylist::addItem(const QUrl &source)
54+{
55+ m_medias << source;
56+ setCurrentIndex(0);
57+ return true;
58+}
59+
60+bool DeclarativePlaylist::addItems(const QList<QUrl> &sources)
61+{
62+ m_medias << sources;
63+ if (!sources.isEmpty())
64+ setCurrentIndex(0);
65+ return true;
66+}
67+
68+bool DeclarativePlaylist::clear()
69+{
70+ m_medias.clear();
71+ setCurrentIndex(-1);
72+ return true;
73+}
tests/mocks/QtMultimedia/declarativeplaylist.hnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef DECLARATIVEPLAYLIST_H
19+#define DECLARATIVEPLAYLIST_H
20+
21+#include <QObject>
22+#include <QUrl>
23+
24+class DeclarativePlaylist : public QObject
25+{
26+ Q_OBJECT
27+ Q_PROPERTY(QUrl currentItemSource READ currentItemSource NOTIFY currentItemSourceChanged)
28+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
29+
30+public:
31+ DeclarativePlaylist(QObject *parent = 0);
32+
33+ QUrl currentItemSource() const;
34+ int currentIndex() const;
35+ void setCurrentIndex(int currentIndex);
36+
37+public Q_SLOTS:
38+ QUrl itemSource(int index) const;
39+ bool addItem(const QUrl &source);
40+ bool addItems(const QList<QUrl> &sources);
41+ bool clear();
42+
43+Q_SIGNALS:
44+ void currentItemSourceChanged();
45+ void currentIndexChanged();
46+
47+private:
48+ Q_DISABLE_COPY(DeclarativePlaylist)
49+
50+ int m_currentIndex;
51+ QList<QUrl> m_medias;
52+};
53+
54+#endif
tests/mocks/QtMultimedia/plugin.cpp+2
@@ -18,6 +18,7 @@
1818
1919#include "plugin.h"
2020#include "audio.h"
21+#include "declarativeplaylist.h"
2122
2223#include <QtQml/qqml.h>
2324
@@ -26,4 +27,5 @@ void MockQtMultimediaPlugin::registerTypes(const char *uri)
2627 Q_ASSERT(uri == QLatin1String("QtMultimedia"));
2728 qmlRegisterType<Audio>(uri, 5, 0, "Audio");
2829 qmlRegisterType<Audio>(uri, 5, 0, "MediaPlayer");
30+ qmlRegisterType<DeclarativePlaylist>(uri, 5, 6, "Playlist");
2931}
tests/mocks/UInput/CMakeLists.txtnew file+7
@@ -0,0 +1,7 @@
1+add_library(FakeUInput-qml MODULE
2+ plugin.cpp
3+ mockuinput.cpp
4+)
5+
6+qt5_use_modules(FakeUInput-qml Qml)
7+add_unity8_mock(UInput 0.1 UInput TARGETS FakeUInput-qml)
tests/mocks/UInput/mockuinput.cppnew file+73
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+
18+#include "mockuinput.h"
19+
20+#include <QFile>
21+#include <QDebug>
22+#include <QDateTime>
23+
24+#include <unistd.h>
25+
26+MockUInput::MockUInput(QObject *parent) :
27+ QObject(parent)
28+{
29+}
30+
31+MockUInput::~MockUInput()
32+{
33+}
34+
35+void MockUInput::createMouse()
36+{
37+ if (m_mouseCreated) {
38+ qDebug() << "Already have a virtual device. Not creating another one.";
39+ return;
40+ }
41+ m_mouseCreated = true;
42+ Q_EMIT mouseCreated();
43+}
44+
45+void MockUInput::removeMouse()
46+{
47+ if (!m_mouseCreated) {
48+ return;
49+ }
50+ qDebug() << "Virtual uinput mouse device removed.";
51+ m_mouseCreated = false;
52+ Q_EMIT mouseRemoved();
53+}
54+
55+void MockUInput::moveMouse(int dx, int dy)
56+{
57+ Q_EMIT mouseMoved(dx, dy);
58+}
59+
60+void MockUInput::pressMouse(Button button)
61+{
62+ Q_EMIT mousePressed(button);
63+}
64+
65+void MockUInput::releaseMouse(Button button)
66+{
67+ Q_EMIT mouseReleased(button);
68+}
69+
70+void MockUInput::scrollMouse(int dh, int dv)
71+{
72+ Q_EMIT mouseScrolled(dh, dv);
73+}
tests/mocks/UInput/mockuinput.hnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+
18+#ifndef MOCKUINPUT_H
19+#define MOCKUINPUT_H
20+
21+#include <QObject>
22+#include <QFile>
23+
24+#include <linux/uinput.h>
25+
26+
27+class MockUInput : public QObject
28+{
29+ Q_OBJECT
30+ Q_ENUMS(Button)
31+
32+public:
33+ enum Button {
34+ ButtonLeft,
35+ ButtonRight,
36+ ButtonMiddle
37+ };
38+
39+ explicit MockUInput(QObject *parent = nullptr);
40+ ~MockUInput();
41+
42+ Q_INVOKABLE void createMouse();
43+ Q_INVOKABLE void removeMouse();
44+
45+ Q_INVOKABLE void moveMouse(int dx, int dy);
46+ Q_INVOKABLE void pressMouse(Button button);
47+ Q_INVOKABLE void releaseMouse(Button button);
48+ Q_INVOKABLE void scrollMouse(int dh, int dv);
49+
50+Q_SIGNALS:
51+ // for testing
52+ void mouseCreated();
53+ void mouseRemoved();
54+ void mouseMoved(int dx, int dy);
55+ void mousePressed(Button button);
56+ void mouseReleased(Button button);
57+ void mouseScrolled(int dh, int dv);
58+
59+private:
60+ bool m_mouseCreated = false;
61+};
62+
63+#endif // MOCKUINPUT_H
tests/mocks/UInput/plugin.cppnew file+26
@@ -0,0 +1,26 @@
1+/*
2+ * Copyright (C) 2015 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "mockuinput.h"
19+
20+#include <QtQml/qqml.h>
21+
22+void MockUInputPlugin::registerTypes(const char *uri)
23+{
24+ Q_ASSERT(uri == QLatin1String("UInput"));
25+ qmlRegisterType<MockUInput>(uri, 0, 1, "UInput");
26+}
tests/mocks/UInput/plugin.hnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef MOCKUINPUT_PLUGIN_H
18+#define MOCKUINPUT_PLUGIN_H
19+
20+#include <QtQml/QQmlEngine>
21+#include <QtQml/QQmlExtensionPlugin>
22+
23+class MockUInputPlugin : public QQmlExtensionPlugin
24+{
25+ Q_OBJECT
26+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
27+
28+public:
29+ void registerTypes(const char *uri) override;
30+};
31+
32+#endif
tests/mocks/UInput/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module UInput
2+plugin FakeUInput-qml
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/CMakeLists.txt+1−1
@@ -7,4 +7,4 @@ add_library(MockSecurityPrivacy MODULE ${MOCK_SECURITYPRIVACY_SOURCES})
77
88qt5_use_modules(MockSecurityPrivacy Qml Quick Core)
99
10−add_unity8_mock(Ubuntu.SystemSettings.SecurityPrivacy 1.0 Ubuntu/SystemSettings/SecurityPrivacy TARGETS MockSecurityPrivacy)
10+add_unity8_mock(Ubuntu.SystemSettings.SecurityPrivacy 1.0 Ubuntu/SystemSettings/SecurityPrivacy PREFIX mocks TARGETS MockSecurityPrivacy)
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.cpp+8−1
@@ -17,12 +17,19 @@
1717#include "MockSecurityPrivacy.h"
1818
1919MockSecurityPrivacy::MockSecurityPrivacy(QObject *parent)
20− : QObject(parent)
20+ : QObject(parent),
21+ m_type(SecurityType::Swipe)
2122{
2223}
2324
25+MockSecurityPrivacy::SecurityType MockSecurityPrivacy::getSecurityType()
26+{
27+ return m_type;
28+}
29+
2430QString MockSecurityPrivacy::setSecurity(const QString &oldPasswd, const QString &newPasswd, SecurityType newType)
2531{
32+ m_type = newType;
2633 Q_EMIT setSecurityCalled(oldPasswd, newPasswd, newType);
2734 return "";
2835}
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.h+8
@@ -23,6 +23,9 @@ class MockSecurityPrivacy : public QObject
2323{
2424 Q_OBJECT
2525 Q_ENUMS(SecurityType)
26+ Q_PROPERTY (SecurityType securityType
27+ READ getSecurityType
28+ NOTIFY securityTypeChanged)
2629
2730public:
2831 enum SecurityType {
@@ -33,10 +36,15 @@ public:
3336
3437 MockSecurityPrivacy(QObject *parent = 0);
3538
39+ SecurityType getSecurityType();
3640 Q_INVOKABLE QString setSecurity(const QString &oldPasswd, const QString &newPasswd, SecurityType newType);
3741
3842Q_SIGNALS:
43+ void securityTypeChanged();
3944 void setSecurityCalled(const QString &oldPasswd, const QString &newPasswd, SecurityType newType); // only in mock
45+
46+private:
47+ SecurityType m_type;
4048};
4149
4250#endif // MOCK_SECURITYPRIVACY_H
tests/mocks/Unity/Application/ApplicationInfo.cpp+14−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -278,3 +278,16 @@ void ApplicationInfo::setExemptFromLifecycle(bool exemptFromLifecycle)
278278 Q_EMIT exemptFromLifecycleChanged(m_exemptFromLifecycle);
279279 }
280280}
281+
282+QSize ApplicationInfo::initialSurfaceSize() const
283+{
284+ return m_initialSurfaceSize;
285+}
286+
287+void ApplicationInfo::setInitialSurfaceSize(const QSize &size)
288+{
289+ if (size != m_initialSurfaceSize) {
290+ m_initialSurfaceSize = size;
291+ Q_EMIT initialSurfaceSizeChanged(m_initialSurfaceSize);
292+ }
293+}
tests/mocks/Unity/Application/ApplicationInfo.h+4−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -95,6 +95,8 @@ public:
9595 bool exemptFromLifecycle() const override;
9696 void setExemptFromLifecycle(bool) override;
9797
98+ QSize initialSurfaceSize() const override;
99+ void setInitialSurfaceSize(const QSize &size) override;
98100public:
99101 void setSession(Session* session);
100102 Session* session() const { return m_session; }
@@ -129,6 +131,7 @@ private:
129131 RequestedState m_requestedState;
130132 bool m_isTouchApp;
131133 bool m_exemptFromLifecycle;
134+ QSize m_initialSurfaceSize;
132135
133136 bool m_manualSurfaceCreation;
134137};
tests/mocks/Unity/Application/ApplicationTestInterface.cpp+4−4
@@ -36,7 +36,7 @@ ApplicationTestInterface::ApplicationTestInterface(QObject* parent)
3636 connection.registerObject("/com/canonical/Unity8/Mocks", parent);
3737}
3838
39−Session* ApplicationTestInterface::addChildSession(Session* existingSession, const QString& surfaceImage)
39+Session* ApplicationTestInterface::addChildSession(Session* existingSession, const QString& surfaceImage, bool addSurface)
4040{
4141 if (!existingSession) return nullptr;
4242
@@ -49,7 +49,7 @@ Session* ApplicationTestInterface::addChildSession(Session* existingSession, con
4949 .arg(existingSession->childSessions()->count()),
5050 screenshotUrl);
5151 existingSession->addChildSession(session);
52− session->createSurface();
52+ if (addSurface) session->createSurface();
5353
5454 return session;
5555}
@@ -70,7 +70,7 @@ void ApplicationTestInterface::removeSurface(MirSurface* existingSurface)
7070 existingSurface->setLive(false);
7171}
7272
73−quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage)
73+quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage, bool addSurface)
7474{
7575 qDebug() << "ApplicationTestInterface::addChildSession to " << appId;
7676
@@ -100,7 +100,7 @@ quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32
100100 .arg(parentSession->childSessions()->count()),
101101 screenshotUrl);
102102 parentSession->addChildSession(session);
103− session->createSurface();
103+ if (addSurface) { session->createSurface(); }
104104 m_childSessions[sessionId] = session;
105105
106106 return sessionId;
tests/mocks/Unity/Application/ApplicationTestInterface.h+2−2
@@ -30,12 +30,12 @@ class ApplicationTestInterface : public QDBusAbstractAdaptor
3030public:
3131 ApplicationTestInterface(QObject* parent = 0);
3232
33− Q_INVOKABLE Session* addChildSession(Session* existingSession, const QString& surfaceImage);
33+ Q_INVOKABLE Session* addChildSession(Session* existingSession, const QString& surfaceImage, bool addSurface);
3434 Q_INVOKABLE void removeSession(Session* existingSession);
3535 Q_INVOKABLE void removeSurface(MirSurface* existingSurface);
3636
3737public Q_SLOTS:
38− quint32 addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage);
38+ quint32 addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage, bool addSurface);
3939 void removeSession(quint32 sessionId);
4040
4141private:
tests/mocks/Unity/Application/MirSurface.cpp+48
@@ -266,3 +266,51 @@ void MirSurface::setSlowToResize(bool value)
266266 }
267267 }
268268}
269+
270+void MirSurface::setMinimumWidth(int value)
271+{
272+ if (value != m_minimumWidth) {
273+ m_minimumWidth = value;
274+ Q_EMIT minimumWidthChanged(m_minimumWidth);
275+ }
276+}
277+
278+void MirSurface::setMaximumWidth(int value)
279+{
280+ if (value != m_maximumWidth) {
281+ m_maximumWidth = value;
282+ Q_EMIT maximumWidthChanged(m_maximumWidth);
283+ }
284+}
285+
286+void MirSurface::setMinimumHeight(int value)
287+{
288+ if (value != m_minimumHeight) {
289+ m_minimumHeight = value;
290+ Q_EMIT minimumHeightChanged(m_minimumHeight);
291+ }
292+}
293+
294+void MirSurface::setMaximumHeight(int value)
295+{
296+ if (value != m_maximumHeight) {
297+ m_maximumHeight = value;
298+ Q_EMIT maximumHeightChanged(m_maximumHeight);
299+ }
300+}
301+
302+void MirSurface::setWidthIncrement(int value)
303+{
304+ if (value != m_widthIncrement) {
305+ m_widthIncrement = value;
306+ Q_EMIT widthIncrementChanged(m_widthIncrement);
307+ }
308+}
309+
310+void MirSurface::setHeightIncrement(int value)
311+{
312+ if (value != m_heightIncrement) {
313+ m_heightIncrement = value;
314+ Q_EMIT heightIncrementChanged(m_heightIncrement);
315+ }
316+}
tests/mocks/Unity/Application/MirSurface.h+21
@@ -66,6 +66,13 @@ public:
6666 Mir::OrientationAngle orientationAngle() const override;
6767 void setOrientationAngle(Mir::OrientationAngle) override;
6868
69+ int minimumWidth() const override { return m_minimumWidth; }
70+ int minimumHeight() const override { return m_minimumHeight; }
71+ int maximumWidth() const override { return m_maximumWidth; }
72+ int maximumHeight() const override { return m_maximumHeight; }
73+ int widthIncrement() const override { return m_widthIncrement; }
74+ int heightIncrement() const override { return m_heightIncrement; }
75+
6976 ////
7077 // API for tests
7178
@@ -82,6 +89,13 @@ public:
8289 bool isSlowToResize() const;
8390 void setSlowToResize(bool value);
8491
92+ Q_INVOKABLE void setMinimumWidth(int);
93+ Q_INVOKABLE void setMaximumWidth(int);
94+ Q_INVOKABLE void setMinimumHeight(int);
95+ Q_INVOKABLE void setMaximumHeight(int);
96+ Q_INVOKABLE void setWidthIncrement(int);
97+ Q_INVOKABLE void setHeightIncrement(int);
98+
8599 /////
86100 // internal mock stuff
87101
@@ -125,6 +139,13 @@ private:
125139 int m_width;
126140 int m_height;
127141
142+ int m_minimumWidth{0};
143+ int m_minimumHeight{0};
144+ int m_maximumWidth{0};
145+ int m_maximumHeight{0};
146+ int m_widthIncrement{0};
147+ int m_heightIncrement{0};
148+
128149 bool m_slowToResize;
129150 QTimer m_delayedResizeTimer;
130151 QSize m_delayedResize;
tests/mocks/Unity/Application/MirSurfaceItem.cpp+6
@@ -37,6 +37,8 @@ MirSurfaceItem::MirSurfaceItem(QQuickItem *parent)
3737 , m_surfaceHeight(0)
3838 , m_touchPressCount(0)
3939 , m_touchReleaseCount(0)
40+ , m_mousePressCount(0)
41+ , m_mouseReleaseCount(0)
4042{
4143// qDebug() << "MirSurfaceItem::MirSurfaceItem() " << (void*)(this) << name();
4244 setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton |
@@ -165,6 +167,8 @@ void MirSurfaceItem::touchEvent(QTouchEvent * event)
165167
166168void MirSurfaceItem::mousePressEvent(QMouseEvent * event)
167169{
170+ m_mousePressCount++;
171+ Q_EMIT mousePressCountChanged(m_mousePressCount);
168172 event->accept();
169173}
170174
@@ -175,6 +179,8 @@ void MirSurfaceItem::mouseMoveEvent(QMouseEvent * event)
175179
176180void MirSurfaceItem::mouseReleaseEvent(QMouseEvent * event)
177181{
182+ m_mouseReleaseCount++;
183+ Q_EMIT mouseReleaseCountChanged(m_mouseReleaseCount);
178184 event->accept();
179185}
180186
tests/mocks/Unity/Application/MirSurfaceItem.h+14
@@ -36,6 +36,10 @@ class MirSurfaceItem : public unity::shell::application::MirSurfaceItemInterface
3636 Q_PROPERTY(int touchReleaseCount READ touchReleaseCount WRITE setTouchReleaseCount
3737 NOTIFY touchReleaseCountChanged DESIGNABLE false)
3838
39+ Q_PROPERTY(int mousePressCount READ mousePressCount WRITE setMousePressCount
40+ NOTIFY mousePressCountChanged)
41+ Q_PROPERTY(int mouseReleaseCount READ mouseReleaseCount WRITE setMouseReleaseCount
42+ NOTIFY mouseReleaseCountChanged)
3943public:
4044 explicit MirSurfaceItem(QQuickItem *parent = 0);
4145 ~MirSurfaceItem();
@@ -76,9 +80,17 @@ public:
7680 int touchReleaseCount() const { return m_touchReleaseCount; }
7781 void setTouchReleaseCount(int count) { m_touchReleaseCount = count; Q_EMIT touchReleaseCountChanged(count); }
7882
83+ int mousePressCount() const { return m_mousePressCount; }
84+ void setMousePressCount(int count) { m_mousePressCount = count; Q_EMIT mousePressCountChanged(count); }
85+
86+ int mouseReleaseCount() const { return m_mouseReleaseCount; }
87+ void setMouseReleaseCount(int count) { m_mouseReleaseCount = count; Q_EMIT mouseReleaseCountChanged(count); }
88+
7989Q_SIGNALS:
8090 void touchPressCountChanged(int count);
8191 void touchReleaseCountChanged(int count);
92+ void mousePressCountChanged(int count);
93+ void mouseReleaseCountChanged(int count);
8294
8395protected:
8496 void touchEvent(QTouchEvent * event) override;
@@ -109,6 +121,8 @@ private:
109121
110122 int m_touchPressCount;
111123 int m_touchReleaseCount;
124+ int m_mousePressCount;
125+ int m_mouseReleaseCount;
112126
113127 FillMode m_fillMode{Stretch};
114128
tests/mocks/Unity/Application/SurfaceManager.cpp+56
@@ -46,6 +46,14 @@ MirSurface *SurfaceManager::createSurface(const QString& name,
4646 MirSurface* surface = qobject_cast<MirSurface*>(obj);
4747 Q_EMIT surfaceDestroyed(surface);
4848 });
49+
50+ surface->setMinimumWidth(m_newSurfaceMinimumWidth);
51+ surface->setMaximumWidth(m_newSurfaceMaximumWidth);
52+ surface->setMinimumHeight(m_newSurfaceMinimumHeight);
53+ surface->setMaximumHeight(m_newSurfaceMaximumHeight);
54+ surface->setWidthIncrement(m_newSurfaceWidthIncrement);
55+ surface->setHeightIncrement(m_newSurfaceHeightIncrement);
56+
4957 Q_EMIT surfaceCreated(surface);
5058 return surface;
5159}
@@ -62,3 +70,51 @@ MirSurface *SurfaceManager::inputMethodSurface()
6270 }
6371 return m_virtualKeyboard;
6472}
73+
74+void SurfaceManager::setNewSurfaceMinimumWidth(int value)
75+{
76+ if (m_newSurfaceMinimumWidth != value) {
77+ m_newSurfaceMinimumWidth = value;
78+ Q_EMIT newSurfaceMinimumWidthChanged(m_newSurfaceMinimumWidth);
79+ }
80+}
81+
82+void SurfaceManager::setNewSurfaceMaximumWidth(int value)
83+{
84+ if (m_newSurfaceMaximumWidth != value) {
85+ m_newSurfaceMaximumWidth = value;
86+ Q_EMIT newSurfaceMaximumWidthChanged(m_newSurfaceMaximumWidth);
87+ }
88+}
89+
90+void SurfaceManager::setNewSurfaceMinimumHeight(int value)
91+{
92+ if (m_newSurfaceMinimumHeight != value) {
93+ m_newSurfaceMinimumHeight = value;
94+ Q_EMIT newSurfaceMinimumHeightChanged(m_newSurfaceMinimumHeight);
95+ }
96+}
97+
98+void SurfaceManager::setNewSurfaceMaximumHeight(int value)
99+{
100+ if (m_newSurfaceMaximumHeight != value) {
101+ m_newSurfaceMaximumHeight = value;
102+ Q_EMIT newSurfaceMaximumHeightChanged(m_newSurfaceMaximumHeight);
103+ }
104+}
105+
106+void SurfaceManager::setNewSurfaceWidthIncrement(int value)
107+{
108+ if (m_newSurfaceWidthIncrement != value) {
109+ m_newSurfaceWidthIncrement = value;
110+ Q_EMIT newSurfaceWidthIncrementChanged(m_newSurfaceWidthIncrement);
111+ }
112+}
113+
114+void SurfaceManager::setNewSurfaceHeightIncrement(int value)
115+{
116+ if (m_newSurfaceHeightIncrement != value) {
117+ m_newSurfaceHeightIncrement = value;
118+ Q_EMIT newSurfaceHeightIncrementChanged(m_newSurfaceHeightIncrement);
119+ }
120+}
tests/mocks/Unity/Application/SurfaceManager.h+40
@@ -25,6 +25,14 @@
2525class SurfaceManager : public QObject
2626{
2727 Q_OBJECT
28+
29+ Q_PROPERTY(int newSurfaceMinimumWidth READ newSurfaceMinimumWidth WRITE setNewSurfaceMinimumWidth NOTIFY newSurfaceMinimumWidthChanged)
30+ Q_PROPERTY(int newSurfaceMaximumWidth READ newSurfaceMaximumWidth WRITE setNewSurfaceMaximumWidth NOTIFY newSurfaceMaximumWidthChanged)
31+ Q_PROPERTY(int newSurfaceMinimumHeight READ newSurfaceMinimumHeight WRITE setNewSurfaceMinimumHeight NOTIFY newSurfaceMinimumHeightChanged)
32+ Q_PROPERTY(int newSurfaceMaximumHeight READ newSurfaceMaximumHeight WRITE setNewSurfaceMaximumHeight NOTIFY newSurfaceMaximumHeightChanged)
33+ Q_PROPERTY(int newSurfaceWidthIncrement READ newSurfaceWidthIncrement WRITE setNewSurfaceWidthIncrement NOTIFY newSurfaceWidthIncrementChanged)
34+ Q_PROPERTY(int newSurfaceHeightIncrement READ newSurfaceHeightIncrement WRITE setNewSurfaceHeightIncrement NOTIFY newSurfaceHeightIncrementChanged)
35+
2836public:
2937 explicit SurfaceManager(QObject *parent = 0);
3038
@@ -38,14 +46,46 @@ public:
3846 // To be used in the tests
3947 Q_INVOKABLE MirSurface* inputMethodSurface();
4048
49+ int newSurfaceMinimumWidth() const { return m_newSurfaceMinimumWidth; }
50+ void setNewSurfaceMinimumWidth(int value);
51+
52+ int newSurfaceMaximumWidth() const { return m_newSurfaceMaximumWidth; }
53+ void setNewSurfaceMaximumWidth(int value);
54+
55+ int newSurfaceMinimumHeight() const { return m_newSurfaceMinimumHeight; }
56+ void setNewSurfaceMinimumHeight(int value);
57+
58+ int newSurfaceMaximumHeight() const { return m_newSurfaceMaximumHeight; }
59+ void setNewSurfaceMaximumHeight(int value);
60+
61+ int newSurfaceWidthIncrement() const { return m_newSurfaceWidthIncrement; }
62+ void setNewSurfaceWidthIncrement(int);
63+
64+ int newSurfaceHeightIncrement() const { return m_newSurfaceHeightIncrement; }
65+ void setNewSurfaceHeightIncrement(int);
66+
4167Q_SIGNALS:
4268 void countChanged();
4369 void surfaceCreated(MirSurface *surface);
4470 void surfaceDestroyed(MirSurface*surface);
4571
72+ void newSurfaceMinimumWidthChanged(int value);
73+ void newSurfaceMaximumWidthChanged(int value);
74+ void newSurfaceMinimumHeightChanged(int value);
75+ void newSurfaceMaximumHeightChanged(int value);
76+ void newSurfaceWidthIncrementChanged(int value);
77+ void newSurfaceHeightIncrementChanged(int value);
78+
4679private:
4780 static SurfaceManager *the_surface_manager;
4881 VirtualKeyboard *m_virtualKeyboard;
82+
83+ int m_newSurfaceMinimumWidth{0};
84+ int m_newSurfaceMaximumWidth{0};
85+ int m_newSurfaceMinimumHeight{0};
86+ int m_newSurfaceMaximumHeight{0};
87+ int m_newSurfaceWidthIncrement{1};
88+ int m_newSurfaceHeightIncrement{1};
4989};
5090
5191#endif // SURFACEMANAGER_H
tests/mocks/Unity/CMakeLists.txt+2−1
@@ -5,9 +5,10 @@ add_subdirectory(InputInfo)
55add_subdirectory(Launcher)
66add_subdirectory(Notifications)
77add_subdirectory(DashCommunicator)
8+add_subdirectory(Screens)
89
910pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
10−pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=8)
11+pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=9)
1112
1213include_directories(
1314 ${CMAKE_CURRENT_BINARY_DIR}
tests/mocks/Unity/Indicators/ModelActionRootState.qml+11−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -30,10 +30,20 @@ Item {
3030 property bool indicatorVisible: cachedState && cachedState.hasOwnProperty("visible") ? cachedState["visible"] : true
3131
3232 property var cachedState: menu ? menu.get(0, "actionState") : undefined
33+ property string submenuAction: {
34+ if (!menu) return "";
35+ var ext = menu.get(0, "ext");
36+ var submenuVar = ext ? ext["submenu-action"] : undefined;
37+ return submenuVar ? submenuVar : ""
38+ }
3339 Connections {
3440 target: menu
3541 onModelDataChanged: {
3642 cachedState = menu.get(0, "actionState");
43+
44+ var ext = menu.get(0, "ext");
45+ var submenuVar = ext ? ext["submenu-action"] : undefined;
46+ submenuAction = submenuVar ? submenuVar : ""
3747 }
3848 }
3949
tests/mocks/Unity/Screens/CMakeLists.txtnew file+14
@@ -0,0 +1,14 @@
1+include_directories(
2+ ${CMAKE_CURRENT_SOURCE_DIR}
3+)
4+
5+set(MockScreens_SOURCES
6+ plugin.cpp
7+ screens.cpp
8+)
9+
10+add_library(MockScreensPlugin MODULE ${MockScreens_SOURCES})
11+
12+qt5_use_modules(MockScreensPlugin Gui Qml)
13+
14+add_unity8_mock(Unity.Screens 0.1 Unity/Screens TARGETS MockScreensPlugin)
tests/mocks/Unity/Screens/plugin.cppnew file+29
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "screens.h"
19+
20+#include <QScreen>
21+
22+void UnityScreensPlugin::registerTypes(const char* uri)
23+{
24+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Screens"));
25+
26+ qRegisterMetaType<QScreen*>("QScreen*");
27+
28+ qmlRegisterType<Screens>(uri, 0, 1, "Screens");
29+}
tests/mocks/Unity/Screens/plugin.hnew file+25
@@ -0,0 +1,25 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include <QQmlExtensionPlugin>
18+#include <QtQml/qqml.h>
19+
20+class UnityScreensPlugin : public QQmlExtensionPlugin {
21+ Q_OBJECT
22+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
23+public:
24+ virtual void registerTypes(const char* uri);
25+};
tests/mocks/Unity/Screens/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Unity.Screens
2+plugin MockScreensPlugin
tests/mocks/Unity/Screens/screens.cppnew file+71
@@ -0,0 +1,71 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "screens.h"
18+
19+// Qt
20+#include <QGuiApplication>
21+#include <QScreen>
22+#include <QDebug>
23+
24+Q_DECLARE_METATYPE(QScreen*)
25+
26+Screens::Screens(QObject *parent) :
27+ QAbstractListModel(parent)
28+{
29+ // start with one screen attached
30+ m_screenList.append(new Screen());
31+}
32+
33+Screens::~Screens()
34+{
35+ qDeleteAll(m_screenList);
36+ m_screenList.clear();
37+}
38+
39+QHash<int, QByteArray> Screens::roleNames() const
40+{
41+ QHash<int, QByteArray> roles;
42+ roles[ScreenRole] = "screen";
43+ roles[OutputTypeRole] = "outputType";
44+ return roles;
45+}
46+
47+QVariant Screens::data(const QModelIndex &index, int role) const
48+{
49+ if (!index.isValid() || index.row() >= m_screenList.size()) {
50+ return QVariant();
51+ }
52+
53+ switch(role) {
54+ case ScreenRole:
55+ return QVariant::fromValue(m_screenList.at(index.row())->qScreen);
56+ case OutputTypeRole:
57+ return m_screenList.at(index.row())->outputTypes;
58+ }
59+
60+ return QVariant();
61+}
62+
63+int Screens::rowCount(const QModelIndex &) const
64+{
65+ return count();
66+}
67+
68+int Screens::count() const
69+{
70+ return m_screenList.size();
71+}
tests/mocks/Unity/Screens/screens.hnew file+82
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef SCREENS_H
18+#define SCREENS_H
19+
20+#include <QAbstractListModel>
21+#include <QScreen>
22+
23+class Screen;
24+
25+class Screens : public QAbstractListModel
26+{
27+ Q_OBJECT
28+ Q_ENUMS(OutputTypes)
29+
30+ Q_PROPERTY(int count READ count NOTIFY countChanged)
31+
32+public:
33+ enum ItemRoles {
34+ ScreenRole = Qt::UserRole + 1,
35+ OutputTypeRole
36+ };
37+
38+ enum OutputTypes {
39+ Unknown,
40+ VGA,
41+ DVII,
42+ DVID,
43+ DVIA,
44+ Composite,
45+ SVideo,
46+ LVDS,
47+ Component,
48+ NinePinDIN,
49+ DisplayPort,
50+ HDMIA,
51+ HDMIB,
52+ TV,
53+ EDP
54+ };
55+
56+ explicit Screens(QObject *parent = 0);
57+ virtual ~Screens() noexcept;
58+
59+ /* QAbstractItemModel */
60+ QHash<int, QByteArray> roleNames() const override;
61+ QVariant data(const QModelIndex &index, int role = ScreenRole) const override;
62+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
63+
64+ int count() const;
65+
66+Q_SIGNALS:
67+ void countChanged();
68+ void screenAdded(QScreen *screen);
69+ void screenRemoved(QScreen *screen);
70+
71+private:
72+ QList<Screen *> m_screenList;
73+};
74+
75+class Screen
76+{
77+public:
78+ Screens::OutputTypes outputTypes = Screens::Unknown;
79+ QScreen *qScreen = nullptr;
80+};
81+
82+#endif // SCREENS_H
tests/mocks/Unity/fake_categories.cpp+1−1
@@ -141,7 +141,7 @@ ResultsModel* Categories::resultModel(int row) const
141141 ResultsModel *result = m_resultsModels[row];
142142 if (!result) {
143143 Categories *that = const_cast<Categories*>(this);
144− result = new ResultsModel(15, row, that);
144+ result = new ResultsModel(25, row, that);
145145 m_resultsModels[row] = result;
146146 }
147147 return result;
tests/mocks/Utils/CMakeLists.txt+1−2
@@ -1,5 +1,3 @@
1−pkg_search_module(GIO REQUIRED gio-2.0)
2−
31include_directories(
42 ${CMAKE_CURRENT_SOURCE_DIR}
53 ${CMAKE_CURRENT_BINARY_DIR}
@@ -19,6 +17,7 @@ set(QMLPLUGIN_SRC
1917 ${CMAKE_SOURCE_DIR}/plugins/Utils/easingcurve.cpp
2018 ${CMAKE_SOURCE_DIR}/plugins/Utils/inputwatcher.cpp
2119 ${CMAKE_SOURCE_DIR}/plugins/Utils/applicationsfiltermodel.cpp
20+ ${CMAKE_SOURCE_DIR}/plugins/Utils/inputeventgenerator.cpp
2221 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
2322 constants.cpp
2423 plugin.cpp
tests/mocks/Utils/HomeKeyWatcher.qml → tests/mocks/Utils/WindowInputMonitor.qmlrenamed+3−1
@@ -17,5 +17,7 @@
1717import QtQuick 2.4
1818
1919QtObject {
20− signal activated()
20+ signal homeKeyActivated()
21+ signal touchBegun()
22+ signal touchEnded(point pos)
2123}
tests/mocks/Utils/plugin.cpp+2
@@ -36,6 +36,7 @@
3636#include <windowscreenshotprovider.h>
3737#include <easingcurve.h>
3838#include <applicationsfiltermodel.h>
39+#include <inputeventgenerator.h>
3940
4041static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
4142{
@@ -65,6 +66,7 @@ void FakeUtilsPlugin::registerTypes(const char *uri)
6566 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
6667 qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
6768 qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel");
69+ qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator");
6870}
6971
7072void FakeUtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
tests/mocks/Utils/qmldir+1−1
@@ -2,5 +2,5 @@ module Utils
22plugin FakeUtils-qml
33typeinfo Utils.qmltypes
44Style 0.1 Style.js
5−HomeKeyWatcher 0.1 HomeKeyWatcher.qml
5+WindowInputMonitor 0.1 WindowInputMonitor.qml
66singleton EdgeBarrierSettings 0.1 EdgeBarrierSettings.qml
tests/mocks/indicator-service/CMakeLists.txt−1
@@ -1,5 +1,4 @@
11project(mock-indicator-service)
2−pkg_search_module(GIO REQUIRED gio-2.0)
32
43set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
54
tests/plugins/Dash/cardcreator/1.res+6−7
@@ -1,6 +1,5 @@
11AbstractButton {
22 id: root;
3− property var components;
43 property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
@@ -24,13 +23,13 @@ Item {
2423 Loader {
2524 id: artShapeLoader;
2625 objectName: "artShapeLoader";
27− active: cardData && cardData["art"] || false;
26+ readonly property string cardArt: cardData && cardData["art"] || "";
27+ active: cardArt != "";
2828 asynchronous: root.asynchronous;
2929 visible: status == Loader.Ready;
3030 sourceComponent: Item {
3131 id: artShape;
3232 objectName: "artShape";
33− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
3433 visible: image.status == Image.Ready;
3534 readonly property alias image: artImage;
3635 ShaderEffectSource {
@@ -39,11 +38,11 @@ Item {
3938 anchors.centerIn: parent;
4039 width: 1;
4140 height: 1;
42− hideSource: doShapeItem;
41+ hideSource: true;
4342 }
4443 Loader {
4544 anchors.fill: parent;
46− visible: artShape.doShapeItem;
45+ visible: true;
4746 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
4847 Component {
4948 id: artShapeShapeComponent;
@@ -67,7 +66,7 @@ Item {
6766 }
6867 }
6968 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
70− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
69+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 1.6;
7170 Component.onCompleted: { updateWidthHeightBindings(); }
7271 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
7372 function updateWidthHeightBindings() {
@@ -82,7 +81,7 @@ Item {
8281 CroppedImageMinimumSourceSize {
8382 id: artImage;
8483 objectName: "artImage";
85− source: cardData && cardData["art"] || "";
84+ source: artShapeLoader.cardArt;
8685 asynchronous: root.asynchronous;
8786 width: root.width;
8887 height: width / artShape.aspect;
tests/plugins/Dash/cardcreator/10.resnew file+141
@@ -0,0 +1,141 @@
1+AbstractButton {
2+ id: root;
3+ property var cardData;
4+ property string artShapeStyle: "inset";
5+ property string backgroundShapeStyle: "inset";
6+ property real fontScale: 1.0;
7+ property var scopeStyle: null;
8+ property int titleAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+ enabled: true;
16+
17+Loader {
18+ id: backgroundLoader;
19+ objectName: "backgroundLoader";
20+ anchors.fill: parent;
21+ asynchronous: root.asynchronous;
22+ visible: status == Loader.Ready;
23+ sourceComponent: UbuntuShape {
24+ objectName: "background";
25+ radius: "medium";
26+ aspect: {
27+ switch (root.backgroundShapeStyle) {
28+ case "inset": return UbuntuShape.Inset;
29+ case "shadow": return UbuntuShape.DropShadow;
30+ default:
31+ case "flat": return UbuntuShape.Flat;
32+ }
33+ }
34+ backgroundColor: getColor(0) || "white";
35+ secondaryBackgroundColor: getColor(1) || backgroundColor;
36+ backgroundMode: UbuntuShape.VerticalGradient;
37+ anchors.fill: parent;
38+ source: backgroundImage.source ? backgroundImage : null;
39+ property real luminance: Style.luminance(backgroundColor);
40+ property Image backgroundImage: Image {
41+ objectName: "backgroundImage";
42+ source: {
43+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
44+ else return "";
45+ }
46+ }
47+ function getColor(index) {
48+ if (cardData && typeof cardData["background"] === "object"
49+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
50+ return cardData["background"]["elements"][index];
51+ } else return index === 0 ? "" : "";
52+ }
53+ }
54+ }
55+readonly property size artShapeSize: Qt.size(-1, -1);
56+readonly property int headerHeight: row.height;
57+Row {
58+ id: row;
59+ objectName: "outerRow";
60+ property real margins: units.gu(1);
61+ spacing: margins;
62+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
63+ anchors { top: parent.top;
64+ topMargin: units.gu(1);
65+left: parent.left;
66+ }
67+ anchors.right: parent.right;
68+ anchors.margins: margins;
69+ anchors.rightMargin: 0;
70+ data: [
71+ CroppedImageMinimumSourceSize {
72+ id: mascotImage;
73+ objectName: "mascotImage";
74+ anchors { verticalCenter: parent.verticalCenter; }
75+ source: cardData && cardData["mascot"] || "";
76+ width: units.gu(6);
77+ height: units.gu(5.625);
78+ horizontalAlignment: Image.AlignHCenter;
79+ verticalAlignment: Image.AlignVCenter;
80+ visible: showHeader;
81+
82+ }
83+,Item {
84+ id: headerTitleContainer;
85+ anchors { verticalCenter: parent.verticalCenter; }
86+ width: parent.width - x;
87+ implicitHeight: titleLabel.height + subtitleLabel.height;
88+ data: [
89+ Label {
90+ id: titleLabel;
91+ objectName: "titleLabel";
92+ anchors { right: parent.right;
93+rightMargin: units.gu(1);
94+left: parent.left;
95+ top: parent.top; }
96+ elide: Text.ElideRight;
97+ fontSize: "small";
98+ wrapMode: Text.Wrap;
99+ maximumLineCount: 2;
100+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
101+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
102+ visible: showHeader ;
103+ width: undefined;
104+ text: root.title;
105+ font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
106+ horizontalAlignment: root.titleAlignment;
107+ }
108+,Label {
109+ id: subtitleLabel;
110+ objectName: "subtitleLabel";
111+ anchors { right: parent.right;
112+ left: parent.left;
113+rightMargin: units.gu(1);
114+top: titleLabel.bottom;
115+ }
116+ anchors.topMargin: units.dp(2);
117+ elide: Text.ElideRight;
118+ maximumLineCount: 1;
119+ fontSize: "x-small";
120+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
121+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
122+ visible: titleLabel.visible && titleLabel.text;
123+ text: cardData && cardData["subtitle"] || "";
124+ font.weight: Font.Light;
125+ }
126+
127+ ]
128+ }
129+
130+ ]
131+ }
132+UbuntuShape {
133+ id: touchdown;
134+ objectName: "touchdown";
135+ anchors { fill: backgroundLoader }
136+ visible: root.artShapeStyle != "shadow" && root.artShapeStyle != "icon" && root.pressed;
137+ radius: "medium";
138+ borderSource: "radius_pressed.sci"
139+ }
140+implicitHeight: row.y + row.height + units.gu(1);
141+}
tests/plugins/Dash/cardcreator/10.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2, "card-background": { "type": "color", "elements": [ "\\", ": 3; } Item { } function moo () { \"" ] } }
2+components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{}}
3+result: 10.res
tests/plugins/Dash/cardcreator/11.resnew file+216
@@ -0,0 +1,216 @@
1+AbstractButton {
2+ id: root;
3+ property var cardData;
4+ property string artShapeStyle: "inset";
5+ property string backgroundShapeStyle: "inset";
6+ property real fontScale: 1.0;
7+ property var scopeStyle: null;
8+ property int titleAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+ enabled: true;
16+
17+Loader {
18+ id: backgroundLoader;
19+ objectName: "backgroundLoader";
20+ anchors.fill: parent;
21+ asynchronous: root.asynchronous;
22+ visible: status == Loader.Ready;
23+ sourceComponent: UbuntuShape {
24+ objectName: "background";
25+ radius: "medium";
26+ aspect: {
27+ switch (root.backgroundShapeStyle) {
28+ case "inset": return UbuntuShape.Inset;
29+ case "shadow": return UbuntuShape.DropShadow;
30+ default:
31+ case "flat": return UbuntuShape.Flat;
32+ }
33+ }
34+ backgroundColor: getColor(0) || "white";
35+ secondaryBackgroundColor: getColor(1) || backgroundColor;
36+ backgroundMode: UbuntuShape.VerticalGradient;
37+ anchors.fill: parent;
38+ source: backgroundImage.source ? backgroundImage : null;
39+ property real luminance: Style.luminance(backgroundColor);
40+ property Image backgroundImage: Image {
41+ objectName: "backgroundImage";
42+ source: {
43+ if (cardData && typeof cardData["background"] === "string") return cardData["background"];
44+ else return "";
45+ }
46+ }
47+ function getColor(index) {
48+ if (cardData && typeof cardData["background"] === "object"
49+ && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
50+ return cardData["background"]["elements"][index];
51+ } else return index === 0 ? "#E9E9E9" : undefined;
52+ }
53+ }
54+ }
55+readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
56+Item {
57+ id: artShapeHolder;
58+ height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height;
59+ width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width;
60+ anchors { horizontalCenter: parent.horizontalCenter; }
61+ Loader {
62+ id: artShapeLoader;
63+ objectName: "artShapeLoader";
64+ readonly property string cardArt: cardData && cardData["art"] || decodeURI("%5C");
65+ active: cardArt != "";
66+ asynchronous: root.asynchronous;
67+ visible: status == Loader.Ready;
68+ sourceComponent: Item {
69+ id: artShape;
70+ objectName: "artShape";
71+ visible: image.status == Image.Ready;
72+ readonly property alias image: artImage;
73+ ShaderEffectSource {
74+ id: artShapeSource;
75+ sourceItem: artImage;
76+ anchors.centerIn: parent;
77+ width: 1;
78+ height: 1;
79+ hideSource: true;
80+ }
81+ Loader {
82+ anchors.fill: parent;
83+ visible: true;
84+ sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
85+ Component {
86+ id: artShapeShapeComponent;
87+ UbuntuShape {
88+ source: artShapeSource;
89+ sourceFillMode: UbuntuShape.PreserveAspectCrop;
90+ radius: "medium";
91+ aspect: {
92+ switch (root.artShapeStyle) {
93+ case "inset": return UbuntuShape.Inset;
94+ case "shadow": return UbuntuShape.DropShadow;
95+ default:
96+ case "flat": return UbuntuShape.Flat;
97+ }
98+ }
99+ }
100+ }
101+ Component {
102+ id: artShapeIconComponent;
103+ ProportionalShape { source: artShapeSource; aspect: UbuntuShape.DropShadow; }
104+ }
105+ }
106+ readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
107+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 1;
108+ Component.onCompleted: { updateWidthHeightBindings(); }
109+ Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
110+ function updateWidthHeightBindings() {
111+ if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
112+ width = root.fixedArtShapeSize.width;
113+ height = root.fixedArtShapeSize.height;
114+ } else {
115+ width = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.width });
116+ height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });
117+ }
118+ }
119+ CroppedImageMinimumSourceSize {
120+ id: artImage;
121+ objectName: "artImage";
122+ source: artShapeLoader.cardArt;
123+ asynchronous: root.asynchronous;
124+ width: root.width;
125+ height: width / artShape.aspect;
126+ onStatusChanged: if (status === Image.Error) source = decodeURI("%5C");
127+ }
128+ }
129+ }
130+ }
131+readonly property int headerHeight: row.height;
132+Row {
133+ id: row;
134+ objectName: "outerRow";
135+ property real margins: units.gu(1);
136+ spacing: margins;
137+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
138+ anchors { top: artShapeHolder.bottom;
139+ topMargin: units.gu(1);
140+left: parent.left;
141+ }
142+ anchors.right: parent.right;
143+ anchors.margins: margins;
144+ anchors.rightMargin: 0;
145+ data: [
146+ CroppedImageMinimumSourceSize {
147+ id: mascotImage;
148+ objectName: "mascotImage";
149+ anchors { verticalCenter: parent.verticalCenter; }
150+ source: cardData && cardData["mascot"] || decodeURI("%22");
151+ width: units.gu(6);
152+ height: units.gu(5.625);
153+ horizontalAlignment: Image.AlignHCenter;
154+ verticalAlignment: Image.AlignVCenter;
155+ visible: showHeader;
156+ onStatusChanged: if (status === Image.Error) source = decodeURI("%22");
157+ }
158+,Item {
159+ id: headerTitleContainer;
160+ anchors { verticalCenter: parent.verticalCenter; }
161+ width: parent.width - x;
162+ implicitHeight: titleLabel.height + subtitleLabel.height;
163+ data: [
164+ Label {
165+ id: titleLabel;
166+ objectName: "titleLabel";
167+ anchors { right: parent.right;
168+rightMargin: units.gu(1);
169+left: parent.left;
170+ top: parent.top; }
171+ elide: Text.ElideRight;
172+ fontSize: "small";
173+ wrapMode: Text.Wrap;
174+ maximumLineCount: 2;
175+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
176+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
177+ visible: showHeader ;
178+ width: undefined;
179+ text: root.title;
180+ font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
181+ horizontalAlignment: root.titleAlignment;
182+ }
183+,Label {
184+ id: subtitleLabel;
185+ objectName: "subtitleLabel";
186+ anchors { right: parent.right;
187+ left: parent.left;
188+rightMargin: units.gu(1);
189+top: titleLabel.bottom;
190+ }
191+ anchors.topMargin: units.dp(2);
192+ elide: Text.ElideRight;
193+ maximumLineCount: 1;
194+ fontSize: "x-small";
195+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
196+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
197+ visible: titleLabel.visible && titleLabel.text;
198+ text: cardData && cardData["subtitle"] || "";
199+ font.weight: Font.Light;
200+ }
201+
202+ ]
203+ }
204+
205+ ]
206+ }
207+UbuntuShape {
208+ id: touchdown;
209+ objectName: "touchdown";
210+ anchors { fill: backgroundLoader }
211+ visible: root.artShapeStyle != "shadow" && root.artShapeStyle != "icon" && root.pressed;
212+ radius: "medium";
213+ borderSource: "radius_pressed.sci"
214+ }
215+implicitHeight: row.y + row.height + units.gu(1);
216+}
tests/plugins/Dash/cardcreator/11.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2 }
2+components: {"art":{"aspect-ratio":1,"field":"art","fallback":"\\"},"background":{"field":"background"},"mascot":{"field":"icon","fallback":"\""},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{}}
3+result: 11.res
tests/plugins/Dash/cardcreator/2.res−1
@@ -1,6 +1,5 @@
11AbstractButton {
22 id: root;
3− property var components;
43 property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
tests/plugins/Dash/cardcreator/3.res+7−7
@@ -1,6 +1,5 @@
11AbstractButton {
22 id: root;
3− property var components;
43 property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
@@ -24,13 +23,13 @@ Item {
2423 Loader {
2524 id: artShapeLoader;
2625 objectName: "artShapeLoader";
27− active: cardData && cardData["art"] || false;
26+ readonly property string cardArt: cardData && cardData["art"] || decodeURI("IHAVE%5C%22ESCAPED%5C%22QUOTES%5C%22");
27+ active: cardArt != "";
2828 asynchronous: root.asynchronous;
2929 visible: status == Loader.Ready;
3030 sourceComponent: Item {
3131 id: artShape;
3232 objectName: "artShape";
33− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
3433 visible: image.status == Image.Ready;
3534 readonly property alias image: artImage;
3635 ShaderEffectSource {
@@ -39,11 +38,11 @@ Item {
3938 anchors.centerIn: parent;
4039 width: 1;
4140 height: 1;
42− hideSource: doShapeItem;
41+ hideSource: true;
4342 }
4443 Loader {
4544 anchors.fill: parent;
46− visible: artShape.doShapeItem;
45+ visible: true;
4746 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
4847 Component {
4948 id: artShapeShapeComponent;
@@ -67,7 +66,7 @@ Item {
6766 }
6867 }
6968 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
70− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
69+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 0.75;
7170 Component.onCompleted: { updateWidthHeightBindings(); }
7271 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
7372 function updateWidthHeightBindings() {
@@ -82,10 +81,11 @@ Item {
8281 CroppedImageMinimumSourceSize {
8382 id: artImage;
8483 objectName: "artImage";
85− source: cardData && cardData["art"] || "";
84+ source: artShapeLoader.cardArt;
8685 asynchronous: root.asynchronous;
8786 width: root.width;
8887 height: width / artShape.aspect;
88+ onStatusChanged: if (status === Image.Error) source = decodeURI("IHAVE%5C%22ESCAPED%5C%22QUOTES%5C%22");
8989 }
9090 }
9191 }
tests/plugins/Dash/cardcreator/3.tst+1−1
@@ -1,3 +1,3 @@
11template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":0.75,"field":"art"},"subtitle":{"field":"price"},"title":{"field":"title"},"attributes":{}}
2+components: {"art":{"aspect-ratio":0.75,"field":"art","fallback":"IHAVE\\\"ESCAPED\\\"QUOTES\\\""},"subtitle":{"field":"price"},"title":{"field":"title"},"attributes":{}}
33result: 3.res
tests/plugins/Dash/cardcreator/4.res−1
@@ -1,6 +1,5 @@
11AbstractButton {
22 id: root;
3− property var components;
43 property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
tests/plugins/Dash/cardcreator/5.res+6−7
@@ -1,6 +1,5 @@
11AbstractButton {
22 id: root;
3− property var components;
43 property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
@@ -24,13 +23,13 @@ Item {
2423 Loader {
2524 id: artShapeLoader;
2625 objectName: "artShapeLoader";
27− active: cardData && cardData["art"] || false;
26+ readonly property string cardArt: cardData && cardData["art"] || "";
27+ active: cardArt != "";
2828 asynchronous: root.asynchronous;
2929 visible: status == Loader.Ready;
3030 sourceComponent: Item {
3131 id: artShape;
3232 objectName: "artShape";
33− readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
3433 visible: image.status == Image.Ready;
3534 readonly property alias image: artImage;
3635 ShaderEffectSource {
@@ -39,11 +38,11 @@ Item {
3938 anchors.centerIn: parent;
4039 width: 1;
4140 height: 1;
42− hideSource: doShapeItem;
41+ hideSource: false;
4342 }
4443 Loader {
4544 anchors.fill: parent;
46− visible: artShape.doShapeItem;
45+ visible: false;
4746 sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent;
4847 Component {
4948 id: artShapeShapeComponent;
@@ -67,7 +66,7 @@ Item {
6766 }
6867 }
6968 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
70− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
69+ readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : 1;
7170 Component.onCompleted: { updateWidthHeightBindings(); }
7271 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
7372 function updateWidthHeightBindings() {
@@ -82,7 +81,7 @@ Item {
8281 CroppedImageMinimumSourceSize {
8382 id: artImage;
8483 objectName: "artImage";
85− source: cardData && cardData["art"] || "";
84+ source: artShapeLoader.cardArt;
8685 asynchronous: root.asynchronous;
8786 width: root.width;
8887 height: width / artShape.aspect;
tests/plugins/Dash/cardcreator/5.tst+1−1
@@ -1,3 +1,3 @@
11template: {"non-interactive":true,"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
2−components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"},"attributes":{}}
2+components: {"art":{"aspect-ratio":1,"field":"art","conciergeMode":true},"subtitle":{"field":"artist"},"title":{"field":"title"},"attributes":{}}
33result: 5.res
tests/plugins/Dash/cardcreator/6.res+1−2
@@ -1,6 +1,5 @@
11AbstractButton {
22 id: root;
3− property var components;
43 property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
@@ -42,7 +41,7 @@ Loader {
4241 objectName: "backgroundImage";
4342 source: {
4443 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
45− else return "http://assets.ubuntu.com/sites/ubuntu/latest/u/img/logos/logo-ubuntu-grey.png";
44+ else return decodeURI("http://assets.ubuntu.com/sites/ubuntu/latest/u/img/logos/logo-ubuntu-grey.png");
4645 }
4746 }
4847 function getColor(index) {
tests/plugins/Dash/cardcreator/7.res−1
@@ -1,6 +1,5 @@
11AbstractButton {
22 id: root;
3− property var components;
43 property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
tests/plugins/Dash/cardcreator/8.res+1−2
@@ -1,7 +1,6 @@
11AbstractButton {
22 id: root;
3− property var components;
4− property var cardData;
3+ property var cardData;
54 property string artShapeStyle: "inset";
65 property string backgroundShapeStyle: "inset";
76 property real fontScale: 1.0;
tests/plugins/Dash/cardcreator/9.resnew file+121
@@ -0,0 +1,121 @@
1+AbstractButton {
2+ id: root;
3+ property var cardData;
4+ property string artShapeStyle: "inset";
5+ property string backgroundShapeStyle: "inset";
6+ property real fontScale: 1.0;
7+ property var scopeStyle: null;
8+ property int titleAlignment: Text.AlignLeft;
9+ property int fixedHeaderHeight: -1;
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
11+ readonly property string title: cardData && cardData["title"] || "";
12+ property bool asynchronous: true;
13+ property bool showHeader: true;
14+ implicitWidth: childrenRect.width;
15+ enabled: true;
16+
17+readonly property size artShapeSize: Qt.size(-1, -1);
18+readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + audioProgressBar.height + audioProgressBar.anchors.topMargin;
19+Label {
20+ id: titleLabel;
21+ objectName: "titleLabel";
22+ anchors { right: parent.right;
23+rightMargin: units.gu(1);
24+left: audioButton.right;
25+ leftMargin: units.gu(1);
26+top: parent.top;
27+ topMargin: units.gu(1);
28+ }
29+ elide: Text.ElideRight;
30+ fontSize: "small";
31+ wrapMode: Text.Wrap;
32+ maximumLineCount: 2;
33+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
34+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
35+ visible: showHeader ;
36+ width: undefined;
37+ text: root.title;
38+ font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
39+ horizontalAlignment: root.titleAlignment;
40+ }
41+Label {
42+ id: subtitleLabel;
43+ objectName: "subtitleLabel";
44+ anchors { left: titleLabel.left;
45+ leftMargin: titleLabel.leftMargin;
46+rightMargin: units.gu(1);
47+right: titleLabel.right;
48+top: titleLabel.bottom;
49+ }
50+ anchors.topMargin: units.dp(2);
51+ elide: Text.ElideRight;
52+ maximumLineCount: 1;
53+ fontSize: "x-small";
54+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
55+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
56+ visible: titleLabel.visible && titleLabel.text;
57+ text: cardData && cardData["subtitle"] || "";
58+ font.weight: Font.Light;
59+ }
60+CardAudioProgress {
61+ id: audioProgressBar;
62+ duration: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["duration"]) || 0;
63+ source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || "";
64+ anchors {
65+ bottom: audioButton.bottom;
66+ left: audioButton.right;
67+ right: parent.right;
68+ margins: units.gu(1);
69+ }
70+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
71+ }AbstractButton {
72+ id: audioButton;
73+ anchors.fill: undefined;
74+ width: height;
75+ height: (root.fixedHeaderHeight > 0 ? root.fixedHeaderHeight : headerHeight) + 2 * units.gu(1);
76+ readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || "";
77+ UbuntuShape {
78+ anchors.fill: parent;
79+ visible: parent.pressed;
80+ radius: "medium";
81+ }
82+ Rectangle {
83+ color: Qt.rgba(0, 0, 0, 0.5);
84+ anchors.centerIn: parent;
85+ width: parent.width * 0.5;
86+ height: width;
87+ radius: width / 2;
88+ }
89+ Icon {
90+ anchors.centerIn: parent;
91+ width: parent.width * 0.3;
92+ height: width;
93+ opacity: 0.9;
94+ name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start";
95+ color: "white";
96+ }
97+ onClicked: {
98+ if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) {
99+ if (DashAudioPlayer.playing) {
100+ DashAudioPlayer.pause();
101+ } else {
102+ DashAudioPlayer.play();
103+ }
104+ } else {
105+ var playlist = (cardData["quickPreviewData"] && cardData["quickPreviewData"]["playlist"]) || null;
106+ DashAudioPlayer.playSource(source, playlist);
107+ }
108+ }
109+ onPressAndHold: {
110+ root.pressAndHold();
111+ }
112+ }UbuntuShape {
113+ id: touchdown;
114+ objectName: "touchdown";
115+ anchors { fill: root }
116+ visible: root.artShapeStyle != "shadow" && root.artShapeStyle != "icon" && root.pressed;
117+ radius: "medium";
118+ borderSource: "radius_pressed.sci"
119+ }
120+implicitHeight: audioButton.height;
121+}
tests/plugins/Dash/cardcreator/9.tstnew file+3
@@ -0,0 +1,3 @@
1+template: {"card-layout":"horizontal","card-size":"medium","category-layout":"grid","collapsed-rows":2,"quick-preview-type": "audio"}
2+components: {"art":{"aspect-ratio":1},"subtitle":{"field":"author"},"title":{"field":"title"}, "quickPreviewData": "quickPreviewData"}
3+result: 9.res
tests/plugins/Dash/cardcreatortest.cpp+1
@@ -64,6 +64,7 @@ private Q_SLOTS:
6464 QVERIFY(lines[0].startsWith(templateString));
6565 QVERIFY(lines[1].startsWith(componentsString));
6666 QVERIFY(lines[2].startsWith(resultString));
67+
6768 const QString templateJSON = lines[0].mid(templateString.length());
6869 const QString componentsJSON = lines[1].mid(componentsString.length());
6970 const QString resultFileName = lines[2].mid(resultString.length());
tests/plugins/Dash/listviewwithpageheadertest.cpp+23
@@ -1954,6 +1954,29 @@ private Q_SLOTS:
19541954 QCOMPARE(lvwph->m_firstVisibleIndex, 0);
19551955 }
19561956
1957+ void testBug1540490()
1958+ {
1959+ lvwph->header()->setImplicitHeight(150);
1960+ verifyItem(0, 150., 150., false);
1961+
1962+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 3), Q_ARG(QVariant, 3));
1963+ model->setProperty(0, "size", 400);
1964+ model->setProperty(1, "size", 600);
1965+ model->setProperty(2, "size", 300);
1966+
1967+ scrollToBottom();
1968+ changeContentY(-200);
1969+
1970+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 2));
1971+ model->setProperty(0, "size", 100);
1972+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 1));
1973+ lvwph->header()->setImplicitHeight(50);
1974+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 200));
1975+
1976+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
1977+ verifyItem(0, 50., 200., false);
1978+ }
1979+
19571980private:
19581981 QQuickView *view;
19591982 ListViewWithPageHeader *lvwph;
tests/plugins/Dash/listviewwithpageheadertest.qml−1
@@ -85,7 +85,6 @@ Rectangle {
8585 pageHeader: Rectangle {
8686 color: "transparent"
8787 width: parent.width
88− height: 50
8988 implicitHeight: 50
9089 Text {
9190 anchors.fill: parent
tests/plugins/Unity/Indicators/CMakeLists.txt−4
@@ -1,7 +1,3 @@
1−pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
2−pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
3−pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
4−
51set(INDICATORS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators)
62set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
73
tests/plugins/Unity/Launcher/launchermodeltest.cpp+2
@@ -61,6 +61,8 @@ public:
6161 bool isTouchApp() const override { return true; }
6262 bool exemptFromLifecycle() const override { return false; }
6363 void setExemptFromLifecycle(bool) override {}
64+ QSize initialSurfaceSize() const override { return QSize(); }
65+ void setInitialSurfaceSize(const QSize &) override {}
6466
6567 // Methods used for mocking (not in the interface)
6668 void setFocused(bool focused) { m_focused = focused; Q_EMIT focusedChanged(focused); }
tests/plugins/Unity/Session/sessionbackendtest.cpp+1
@@ -149,6 +149,7 @@ private Q_SLOTS:
149149 }
150150
151151 void testLogin1Capabilities() {
152+ QSKIP("This test talks to real logind backend, it will fail depending on how the machine is set up");
152153 DBusUnitySessionService dbusUnitySessionService;
153154 QDBusInterface login1face("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
154155 QCoreApplication::processEvents(); // to let the services register on DBus
tests/plugins/Utils/CMakeLists.txt+1−1
@@ -7,7 +7,7 @@ include_directories(
77foreach(util_test
88 QLimitProxyModel
99 UnitySortFilterProxyModel
10− HomeKeyWatcher
10+ WindowInputMonitor
1111)
1212 add_executable(${util_test}TestExec ${util_test}Test.cpp ModelTest.cpp)
1313 qt5_use_modules(${util_test}TestExec Test Core Qml)
tests/plugins/Utils/HomeKeyWatcherTest.cpp → tests/plugins/Utils/WindowInputMonitorTest.cpprenamed+14−14
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−#include "HomeKeyWatcher.h"
17+#include "WindowInputMonitor.h"
1818
1919#include <QTest>
2020#include <QSignalSpy>
@@ -71,7 +71,7 @@ public:
7171
7272using namespace UnityUtil;
7373
74−class HomeKeyWatcherTest : public QObject {
74+class WindowInputMonitorTest : public QObject {
7575 Q_OBJECT
7676private Q_SLOTS:
7777 void init(); // called right before each and every test function is executed
@@ -88,25 +88,25 @@ private:
8888 FakeTimerFactory *m_fakeTimerFactory;
8989};
9090
91−void HomeKeyWatcherTest::init()
91+void WindowInputMonitorTest::init()
9292{
9393 m_fakeTimerFactory = new FakeTimerFactory;
9494}
9595
96−void HomeKeyWatcherTest::cleanup()
96+void WindowInputMonitorTest::cleanup()
9797{
9898 delete m_fakeTimerFactory;
9999 m_fakeTimerFactory = nullptr;
100100}
101101
102102
103−void HomeKeyWatcherTest::passTime(qint64 timeSpanMs)
103+void WindowInputMonitorTest::passTime(qint64 timeSpanMs)
104104{
105105 qint64 finalTime = FakeElapsedTimer::msecsSinceEpoch + timeSpanMs;
106106 m_fakeTimerFactory->updateTime(finalTime);
107107}
108108
109−void HomeKeyWatcherTest::touchTapTouch_data()
109+void WindowInputMonitorTest::touchTapTouch_data()
110110{
111111 QTest::addColumn<int>("silenceBeforeTap");
112112 QTest::addColumn<int>("tapDuration");
@@ -121,14 +121,14 @@ void HomeKeyWatcherTest::touchTapTouch_data()
121121 QTest::newRow("isolated long press") << 1000 << 200 << 1000 << 0;
122122}
123123
124−void HomeKeyWatcherTest::touchTapTouch()
124+void WindowInputMonitorTest::touchTapTouch()
125125{
126126 QFETCH(int, silenceBeforeTap);
127127 QFETCH(int, tapDuration);
128128 QFETCH(int, silenceAfterTap);
129129 QFETCH(int, expectedActivatedCount);
130− HomeKeyWatcher homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
131− QSignalSpy activatedSpy(&homeKeyWatcher, &HomeKeyWatcher::activated);
130+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
131+ QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
132132 QVERIFY(activatedSpy.isValid());
133133
134134 {
@@ -186,10 +186,10 @@ void HomeKeyWatcherTest::touchTapTouch()
186186 QCOMPARE(activatedSpy.count(), expectedActivatedCount);
187187}
188188
189−void HomeKeyWatcherTest::tapWhileTouching()
189+void WindowInputMonitorTest::tapWhileTouching()
190190{
191− HomeKeyWatcher homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
192− QSignalSpy activatedSpy(&homeKeyWatcher, &HomeKeyWatcher::activated);
191+ WindowInputMonitor homeKeyWatcher(m_fakeTimerFactory->create(), new FakeElapsedTimer);
192+ QSignalSpy activatedSpy(&homeKeyWatcher, &WindowInputMonitor::homeKeyActivated);
193193 QVERIFY(activatedSpy.isValid());
194194
195195 {
@@ -318,6 +318,6 @@ AbstractTimer *FakeTimerFactory::create(QObject *parent)
318318 return fakeTimer;
319319}
320320
321−QTEST_GUILESS_MAIN(HomeKeyWatcherTest)
321+QTEST_GUILESS_MAIN(WindowInputMonitorTest)
322322
323−#include "HomeKeyWatcherTest.moc"
323+#include "WindowInputMonitorTest.moc"
tests/qmltests/CMakeLists.txt+4−2
@@ -12,11 +12,12 @@ add_unity8_qmltest(Components DraggingArea)
1212add_unity8_qmltest(Components LazyImage)
1313add_unity8_qmltest(Components Lockscreen)
1414add_unity8_qmltest(Components ModeSwitchWarningDialog)
15−add_unity8_qmlunittest(Components PhysicalKeysMapper)
15+add_unity8_qmltest(Components PhysicalKeysMapper)
1616add_unity8_qmltest(Components Rating)
1717add_unity8_qmltest(Components ResponsiveGridView)
1818add_unity8_qmltest(Components ResponsiveVerticalJournal)
1919add_unity8_qmltest(Components Showable)
20+add_unity8_qmltest(Components VirtualTouchPad)
2021add_unity8_qmltest(Components WallpaperResolver)
2122add_unity8_qmltest(Components ZoomableImage)
2223add_unity8_qmltest(Dash Dash)
@@ -38,6 +39,7 @@ add_unity8_qmltest(Dash/Previews PreviewExpandable)
3839add_unity8_qmltest(Dash/Previews PreviewHeader)
3940add_unity8_qmltest(Dash/Previews PreviewIconActions)
4041add_unity8_qmltest(Dash/Previews PreviewImageGallery)
42+add_unity8_qmltest(Dash/Previews PreviewMediaToolbar)
4143add_unity8_qmltest(Dash/Previews PreviewPayments)
4244add_unity8_qmltest(Dash/Previews PreviewProgress)
4345add_unity8_qmltest(Dash/Previews PreviewRatingDisplay)
@@ -87,4 +89,4 @@ add_unity8_qmltest(Stages WindowResizeArea)
8789add_unity8_qmltest(Stages Splash)
8890add_unity8_qmltest(Tutorial Tutorial LIGHTDM)
8991add_unity8_qmltest(Wizard Wizard ENVIRONMENT "OXIDE_NO_SANDBOX=1")
90−add_unity8_qmlunittest(utils/Unity/Test UnityTest)
92+add_unity8_qmltest(utils/Unity/Test UnityTest)
tests/qmltests/Components/CMakeLists.txt+1−1
@@ -15,7 +15,7 @@ qt5_use_modules(DragHandleTestExec Test Core Qml Gui Quick)
1515target_link_libraries(DragHandleTestExec UbuntuGesturesQml UbuntuGestures)
1616
1717add_unity8_uitest(DragHandle DragHandleTestExec ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures)
18−add_manual_qml_test(. DragHandle IMPORT_PATHS ${UNITY_PLUGINPATH})
18+add_manual_qml_test(. DragHandle IMPORT_PATHS ${UNITY_IMPORT_PATHS})
1919
2020########## tst_EdgeDragEvaluator
2121add_executable(EdgeDragEvaluatorTestExec tst_EdgeDragEvaluator.cpp)
tests/qmltests/Components/tst_DragHandle.qml+6−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -51,7 +51,7 @@ Rectangle {
5151 objectName: "baseItem"
5252 anchors.fill: parent
5353
54− Button {
54+ SimpleButton {
5555 visible: root.bidirectional && bidirectionalShowable.fullyHidden
5656 text: "bidirectionalShowable.show()"
5757 anchors.centerIn: parent
@@ -169,12 +169,12 @@ Rectangle {
169169 anchors.margins: units.gu(1)
170170 spacing: units.gu(1)
171171
172− Button {
172+ SimpleButton {
173173 text: root.stretch ? "stretch" : "move"
174174 onClicked: { root.stretch = !root.stretch; }
175175 }
176176
177− Button {
177+ SimpleButton {
178178 text: root.hintDisplacement > 0 ? "hint" : "no hint"
179179 onClicked: {
180180 if (root.hintDisplacement > 0) {
@@ -185,7 +185,7 @@ Rectangle {
185185 }
186186 }
187187
188− Button {
188+ SimpleButton {
189189 text: "rotation: " + baseItem.rotation
190190 onClicked: {
191191 if (baseItem.rotation === 0.0) {
@@ -196,7 +196,7 @@ Rectangle {
196196 }
197197 }
198198
199− Button {
199+ SimpleButton {
200200 text: root.bidirectional ? "bidirectional" : "directional"
201201 onClicked: { root.bidirectional = !root.bidirectional; }
202202 }
tests/qmltests/Components/tst_DragHandle/SimpleButton.qmlnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+
20+
21+Rectangle {
22+ id: root
23+ property alias text: textItem.text
24+ signal clicked()
25+ width: textItem.width + units.gu(1.5)
26+ height: textItem.height + units.gu(1.5)
27+ Text {
28+ id: textItem
29+ anchors.centerIn: parent
30+ font.pixelSize: units.gu(1.5)
31+ }
32+ MouseArea {
33+ anchors.fill: parent
34+ onClicked: root.clicked()
35+ }
36+}
tests/qmltests/Components/tst_LazyImage.qml+27−8
@@ -112,6 +112,11 @@ Rectangle {
112112 }
113113 }
114114
115+ SignalSpy {
116+ id: signalSpy
117+ signalName: "runningChanged"
118+ }
119+
115120 UT.UnityTestCase {
116121 name: "LazyImage"
117122 when: windowShown
@@ -123,6 +128,18 @@ Rectangle {
123128 tryCompare(lazy2, "height", units.gu(10));
124129 controls3.blank();
125130 tryCompare(lazy3, "width", units.gu(10));
131+
132+ tryCompare(lazy1, "state", "default");
133+ var transition = findChildIn(lazy1, "transitions", "genericTransition");
134+ tryCompare(transition, "running", false);
135+
136+ tryCompare(lazy2, "state", "default");
137+ transition = findChildIn(lazy2, "transitions", "genericTransition");
138+ tryCompare(transition, "running", false);
139+
140+ tryCompare(lazy3, "state", "default");
141+ transition = findChildIn(lazy3, "transitions", "genericTransition");
142+ tryCompare(transition, "running", false);
126143 }
127144
128145 function test_lazyimage_data() {
@@ -131,32 +148,34 @@ Rectangle {
131148 {tag: "Unbound Wide", image: lazy1, func: controls1.wide, transition: "readyTransition", width: 160, height: 80, imageWidth: 160, imageHeight: 80, initialWidth: units.gu(10), initialHeight: units.gu(10)},
132149 {tag: "Unbound Square", image: lazy1, func: controls1.square, transition: "readyTransition", width: 160, height: 160, imageWidth: 160, imageHeight: 160, initialWidth: units.gu(10), initialHeight: units.gu(10)},
133150 {tag: "Unbound Portrait", image: lazy1, func: controls1.portrait, transition: "readyTransition", width: 80, height: 160, imageWidth: 80, imageHeight: 160, initialWidth: units.gu(10), initialHeight: units.gu(10)},
134− {tag: "Unbound Bad path", image: lazy1, func: controls1.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(10), imageWidth: units.gu(10), imageHeight: units.gu(10), initialWidth: units.gu(10), initialHeight: units.gu(10), placeholder: true, error: true},
151+ {tag: "Unbound Bad path", image: lazy1, func: controls1.badpath, transition: "genericTransition", state: "error", width: units.gu(10), height: units.gu(10), imageWidth: units.gu(10), imageHeight: units.gu(10), initialWidth: units.gu(10), initialHeight: units.gu(10), placeholder: true, error: true},
135152 {tag: "Width-bound Blank", image: lazy2, func: controls2.blank, width: units.gu(30), height: units.gu(10), imageWidth: units.gu(30), imageHeight: units.gu(10), initialWidth: units.gu(30), initialHeight: units.gu(10), placeholder: true},
136153 {tag: "Width-bound Wide", image: lazy2, func: controls2.wide, transition: "readyTransition", width: units.gu(30), height: units.gu(15), imageWidth: units.gu(30), imageHeight: units.gu(15), initialWidth: units.gu(30), initialHeight: units.gu(10)},
137154 {tag: "Width-bound Square", image: lazy2, func: controls2.square, transition: "readyTransition", width: units.gu(30), height: units.gu(30), imageWidth: units.gu(30), imageHeight: units.gu(30), initialWidth: units.gu(30), initialHeight: units.gu(10)},
138155 {tag: "Width-bound Portrait", image: lazy2, func: controls2.portrait, transition: "readyTransition", width: units.gu(30), height: units.gu(60), imageWidth: units.gu(30), imageHeight: units.gu(60), initialWidth: units.gu(30), initialHeight: units.gu(10)},
139− {tag: "Width-bound Bad path", image: lazy2, func: controls2.badpath, transition: "genericTransition", width: units.gu(30), height: units.gu(10), imageWidth: units.gu(30), imageHeight: units.gu(10), initialWidth: units.gu(30), initialHeight: units.gu(10), placeholder: true, error: true},
156+ {tag: "Width-bound Bad path", image: lazy2, func: controls2.badpath, transition: "genericTransition", state: "error", width: units.gu(30), height: units.gu(10), imageWidth: units.gu(30), imageHeight: units.gu(10), initialWidth: units.gu(30), initialHeight: units.gu(10), placeholder: true, error: true},
140157 {tag: "Height-bound Blank", image: lazy3, func: controls3.blank, width: units.gu(10), height: units.gu(12), imageWidth: units.gu(10), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12), placeholder: true},
141158 {tag: "Height-bound Wide", image: lazy3, func: controls3.wide, transition: "readyTransition", width: units.gu(24), height: units.gu(12), imageWidth: units.gu(24), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
142159 {tag: "Height-bound Square", image: lazy3, func: controls3.square, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
143160 {tag: "Height-bound Portrait", image: lazy3, func: controls3.portrait, transition: "readyTransition", width: units.gu(6), height: units.gu(12), imageWidth: units.gu(6), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12)},
144− {tag: "Height-bound Bad path", image: lazy3, func: controls3.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(12), imageWidth: units.gu(10), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12), placeholder: true, error: true},
161+ {tag: "Height-bound Bad path", image: lazy3, func: controls3.badpath, transition: "genericTransition", state: "error", width: units.gu(10), height: units.gu(12), imageWidth: units.gu(10), imageHeight: units.gu(12), initialWidth: units.gu(10), initialHeight: units.gu(12), placeholder: true, error: true},
145162 {tag: "Fit Blank", image: lazy4, func: controls4.blank, width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12), placeholder: true},
146163 {tag: "Fit Wide", image: lazy4, func: controls4.wide, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(6), initialWidth: units.gu(12), initialHeight: units.gu(12)},
147164 {tag: "Fit Square", image: lazy4, func: controls4.square, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12)},
148165 {tag: "Fit Portrait", image: lazy4, func: controls4.portrait, transition: "readyTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(6), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12)},
149− {tag: "Fit Bad path", image: lazy4, func: controls4.badpath, transition: "genericTransition", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12), placeholder: true, error: true},
166+ {tag: "Fit Bad path", image: lazy4, func: controls4.badpath, transition: "genericTransition", state: "error", width: units.gu(12), height: units.gu(12), imageWidth: units.gu(12), imageHeight: units.gu(12), initialWidth: units.gu(12), initialHeight: units.gu(12), placeholder: true, error: true},
150167 ]
151168 }
152169
153170 function test_lazyimage(data) {
171+ var transition = findChildIn(data.image, "transitions", data.transition);
172+ signalSpy.target = transition;
173+ signalSpy.clear();
174+
154175 data.func();
155176
156177 if (data.transition) {
157− // wait for the transition to complete
158− var transition = findChildIn(data.image, "transitions", data.transition);
159− tryCompare(transition, "running", true);
178+ tryCompare(data.image, "state", data.state ? data.state : "ready");
160179 tryCompare(transition, "running", false);
161180 }
162181
@@ -185,7 +204,7 @@ Rectangle {
185204
186205 // check the error image
187206 var error = findChild(data.image, "errorImage");
188− compare(error.visible, data.error ? true : false);
207+ tryCompare(error, "visible", data.error ? true : false);
189208 }
190209 }
191210}
tests/qmltests/Components/tst_PhysicalKeysMapper.qml+136−62
@@ -18,12 +18,19 @@ import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Components"
2020import Powerd 0.1
21+import Utils 0.1
2122
22−TestCase {
23− name: "PhysicalKeysMapper"
23+Item {
24+ width: 100
25+ height: 100
2426
2527 property var physicalKeysMapper: loader.item
2628
29+ WindowKeysFilter {
30+ Keys.onPressed: physicalKeysMapper.onKeyPressed(event, currentEventTimestamp);
31+ Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
32+ }
33+
2734 Loader {
2835 // Using a Loader here to make sure mapper state is coherent
2936 // regardless of unmatched KeyPress and KeyRelease events
@@ -32,6 +39,21 @@ TestCase {
3239 sourceComponent: PhysicalKeysMapper { }
3340 }
3441
42+ Item {
43+ id: inputCatcher
44+ focus: true
45+
46+ property var pressedKeys: []
47+ property var releasedKeys: []
48+
49+ Keys.onPressed: {
50+ inputCatcher.pressedKeys.push(event.key);
51+ }
52+ Keys.onReleased: {
53+ inputCatcher.releasedKeys.push(event.key);
54+ }
55+ }
56+
3557 SignalSpy {
3658 id: powerSpy
3759 target: physicalKeysMapper
@@ -44,65 +66,117 @@ TestCase {
4466 signalName: "screenshotTriggered"
4567 }
4668
47− function init() {
48− Powerd.setStatus(Powerd.On, Powerd.Unknown);
49− loader.active = true;
50− tryCompare(loader.status == Loader.Ready);
51− }
52−
53− function cleanup() {
54− loader.active = false;
55− powerSpy.clear();
56− screenshotSpy.clear();
57− }
58−
59− function test_powerKeyLongPressed_data() {
60− return [
61− { tag: "screenOn", status: Powerd.On },
62− { tag: "screenOff", status: Powerd.Off },
63− ];
64− }
65−
66− function test_powerKeyLongPressed(data) {
67− Powerd.setStatus(data.status, Powerd.Unknown);
68− physicalKeysMapper.powerKeyLongPressTime = 500;
69−
70− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: false }, 100);
71−
72− // After the first key press the screen is always on
73− // and the rest of keypresses are auto repeat
74− Powerd.setStatus(Powerd.On, Powerd.Unknown);
75−
76− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 300);
77− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 400);
78− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 500);
79− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 599);
80−
81− // powerKeyLongPressed should not have been emitted yet.
82− compare(powerSpy.count, 0);
83−
84− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 600);
85−
86− compare(powerSpy.count, 1);
87−
88− // Confirm we only emit once
89− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 601);
90− compare(powerSpy.count, 1);
91− }
92−
93− function test_screenshotButtons_data() {
94− return [
95− { tag: "UpFirst", first: Qt.Key_VolumeUp, second: Qt.Key_VolumeDown },
96− { tag: "DownFirst", first: Qt.Key_VolumeDown, second: Qt.Key_VolumeUp },
97− ];
98− }
99−
100− function test_screenshotButtons(data) {
101− physicalKeysMapper.onKeyPressed({ key: data.first });
102− physicalKeysMapper.onKeyPressed({ key: data.second });
103− screenshotSpy.wait();
104− physicalKeysMapper.onKeyReleased({ key: data.first });
105− physicalKeysMapper.onKeyReleased({ key: data.second });
106− compare(screenshotSpy.count, 1);
69+ TestCase {
70+ name: "PhysicalKeysMapper"
71+ when: windowShown
72+
73+ function init() {
74+ Powerd.setStatus(Powerd.On, Powerd.Unknown);
75+ loader.active = true;
76+ tryCompare(loader.status == Loader.Ready);
77+ inputCatcher.pressedKeys = [];
78+ inputCatcher.releasedKeys = [];
79+ }
80+
81+ function cleanup() {
82+ loader.active = false;
83+ powerSpy.clear();
84+ screenshotSpy.clear();
85+ }
86+
87+ function test_powerKeyLongPressed_data() {
88+ return [
89+ { tag: "screenOn", status: Powerd.On },
90+ { tag: "screenOff", status: Powerd.Off },
91+ ];
92+ }
93+
94+ function test_powerKeyLongPressed(data) {
95+ Powerd.setStatus(data.status, Powerd.Unknown);
96+ physicalKeysMapper.powerKeyLongPressTime = 500;
97+
98+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: false }, 100);
99+
100+ // After the first key press the screen is always on
101+ // and the rest of keypresses are auto repeat
102+ Powerd.setStatus(Powerd.On, Powerd.Unknown);
103+
104+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 300);
105+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 400);
106+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 500);
107+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 599);
108+
109+ // powerKeyLongPressed should not have been emitted yet.
110+ compare(powerSpy.count, 0);
111+
112+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 600);
113+
114+ compare(powerSpy.count, 1);
115+
116+ // Confirm we only emit once
117+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 601);
118+ compare(powerSpy.count, 1);
119+ }
120+
121+ function test_screenshotButtons_data() {
122+ return [
123+ { tag: "UpFirst", first: Qt.Key_VolumeUp, second: Qt.Key_VolumeDown },
124+ { tag: "DownFirst", first: Qt.Key_VolumeDown, second: Qt.Key_VolumeUp },
125+ ];
126+ }
127+
128+ function test_screenshotButtons(data) {
129+ physicalKeysMapper.onKeyPressed({ key: data.first });
130+ physicalKeysMapper.onKeyPressed({ key: data.second });
131+ screenshotSpy.wait();
132+ physicalKeysMapper.onKeyReleased({ key: data.first });
133+ physicalKeysMapper.onKeyReleased({ key: data.second });
134+ compare(screenshotSpy.count, 1);
135+ }
136+
137+ function test_altIsDispatchedOnRelease() {
138+ // Press alt, make sure it does *not* end up in inputCatcher (aka, the focused app)
139+ keyPress(Qt.Key_Alt, Qt.NoModifier)
140+ compare(inputCatcher.pressedKeys.length, 0);
141+ // Now release alt. It should cause the previous Alt press to be dispatched along with the release
142+ keyRelease(Qt.Key_Alt, Qt.NoModifier);
143+ compare(inputCatcher.pressedKeys.length, 1);
144+ compare(inputCatcher.pressedKeys[0], Qt.Key_Alt);
145+ compare(inputCatcher.releasedKeys.length, 1);
146+ compare(inputCatcher.releasedKeys[0], Qt.Key_Alt);
147+ }
148+
149+ function test_altIsNotDispatchedOnAltTab() {
150+ // Press alt, make sure it does *not* end up in inputCatcher (aka, the focused app)
151+ inputCatcher.pressedKeys = [];
152+ keyPress(Qt.Key_Alt, Qt.NoModifier)
153+ compare(inputCatcher.pressedKeys.length, 0);
154+ // Now also press tab. As this should trigger the spread, neither of them should end up in the app
155+ keyPress(Qt.Key_Tab, Qt.NoModifier)
156+ compare(inputCatcher.pressedKeys.length, 0);
157+
158+ // Also the release events should not be dispatched to the app
159+ keyRelease(Qt.Key_Tab, Qt.NoModifier);
160+ keyRelease(Qt.Key_Alt, Qt.NoModifier);
161+ compare(inputCatcher.pressedKeys.length, 0);
162+ compare(inputCatcher.releasedKeys.length, 0);
163+ }
164+
165+ function test_altComboIsDispatched() {
166+ inputCatcher.pressedKeys = [];
167+ // Press alt, make sure it does *not* yet end up in inputCatcher (aka, the focused app)
168+ keyPress(Qt.Key_Alt, Qt.NoModifier)
169+ compare(inputCatcher.pressedKeys.length, 0);
170+ // Now press F in order to opening the File menu (Alt+F), now the app should get the full combo
171+ keyPress(Qt.Key_F, Qt.NoModifier)
172+ compare(inputCatcher.pressedKeys.length, 2);
173+ compare(inputCatcher.pressedKeys[0], Qt.Key_Alt);
174+ compare(inputCatcher.pressedKeys[1], Qt.Key_F);
175+
176+ // release them both, both are supposed to end up in the app
177+ keyRelease(Qt.Key_F, Qt.NoModifier);
178+ keyRelease(Qt.Key_Alt, Qt.NoModifier);
179+ compare(inputCatcher.releasedKeys.length, 2);
180+ }
107181 }
108182}
tests/qmltests/Components/tst_ResponsiveGridView.qml−36
@@ -32,12 +32,6 @@ Item {
3232 height: parent.height
3333 anchors.top: parent.top
3434 anchors.right: parent.right
35− ListItem.ValueSelector {
36− id: maxColumnsSelector
37− text: "maximumNumberOfColumns"
38− values: [2,4,8,13,1000]
39− selectedIndex: 1
40− }
4135 ListItem.ValueSelector {
4236 id: minHSpacingSelector
4337 text: "minHorizontalSpacing"
@@ -86,8 +80,6 @@ Item {
8680 minimumHorizontalSpacing:
8781 minHSpacingSelector.values[minHSpacingSelector.selectedIndex]
8882 verticalSpacing: units.gu(2)
89− maximumNumberOfColumns:
90− maxColumnsSelector.values[maxColumnsSelector.selectedIndex]
9183 delegateWidth: units.gu(6)
9284 delegateHeight: units.gu(6)
9385
@@ -123,31 +115,6 @@ Item {
123115 name: "ResponsiveGridView"
124116 when: windowShown
125117
126− function test_maximumNumberOfColumns_data() {
127− var data = new Array()
128−
129− data.push({selectedIndex: 0, maxColumnCount:2, columnCount: 2})
130− data.push({selectedIndex: 1, maxColumnCount:4, columnCount: 4})
131− data.push({selectedIndex: 2, maxColumnCount:8, columnCount: 8})
132− data.push({selectedIndex: 4, maxColumnCount:1000, columnCount: 13})
133−
134− return data
135− }
136−
137− /* Change ResponsiveGridView's maximumNumberOfColumns property and check
138− that the resulting number of columns matches expectations */
139− function test_maximumNumberOfColumns(data) {
140− minHSpacingSelector.selectedIndex = 0
141−
142− // sanity checks
143− compare(maxColumnsSelector.values[data.selectedIndex], data.maxColumnCount)
144− compare(minHSpacingSelector.values[0], 0)
145−
146− maxColumnsSelector.selectedIndex = data.selectedIndex
147− tryCompareFunction(countGridDelegatesOnFirstRow, data.columnCount);
148− compare(grid.columns, data.columnCount)
149− }
150−
151118 function test_minimumHorizontalSpacing_data() {
152119 var data = new Array()
153120
@@ -162,10 +129,7 @@ Item {
162129 /* Change ResponsiveGridView's minimumHorizontalSpacing property and check
163130 that the resulting number of columns matches expectations */
164131 function test_minimumHorizontalSpacing(data) {
165− maxColumnsSelector.selectedIndex = 4
166−
167132 // sanity checks
168− compare(maxColumnsSelector.values[4], 1000)
169133 compare(minHSpacingSelector.values[data.selectedIndex], data.minHSpacing)
170134
171135 minHSpacingSelector.selectedIndex = data.selectedIndex
tests/qmltests/Components/tst_VirtualTouchPad.qmlnew file+143
@@ -0,0 +1,143 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtTest 1.0
19+import Unity.Test 0.1
20+import UInput 0.1
21+import "../../../qml/Components"
22+
23+
24+Item {
25+ id: root
26+ width: units.gu(70)
27+ height: units.gu(70)
28+
29+ VirtualTouchPad {
30+ id: touchScreenPad
31+ anchors.fill: parent
32+ }
33+
34+ SignalSpy {
35+ id: mouseEventSpy1
36+ target: touchScreenPad.uinput
37+ }
38+ SignalSpy {
39+ id: mouseEventSpy2
40+ target: touchScreenPad.uinput
41+ }
42+
43+ UnityTestCase {
44+ id: testCase
45+ name: "VirtualTouchPad"
46+ when: windowShown
47+
48+ function init() {
49+ mouseEventSpy1.clear();
50+ mouseEventSpy2.clear();
51+ }
52+
53+ function test_click() {
54+ mouseEventSpy1.signalName = "mousePressed"
55+ mouseEventSpy2.signalName = "mouseReleased"
56+
57+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
58+
59+ tap(touchPadArea)
60+ tryCompare(mouseEventSpy1, "count", 1)
61+ tryCompare(mouseEventSpy2, "count", 1)
62+ }
63+
64+ function test_doubleClick() {
65+ mouseEventSpy1.signalName = "mousePressed"
66+ mouseEventSpy2.signalName = "mouseReleased"
67+
68+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
69+
70+ tap(touchPadArea)
71+ tap(touchPadArea)
72+
73+ tryCompare(mouseEventSpy1, "count", 2)
74+ tryCompare(mouseEventSpy2, "count", 2)
75+ }
76+
77+ function test_move() {
78+ mouseEventSpy1.signalName = "mouseMoved"
79+
80+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
81+
82+ var moveDiff = units.gu(2);
83+ var moveSteps = 5;
84+
85+ touchFlick(touchPadArea, units.gu(1), units.gu(1), units.gu(1) + moveDiff, units.gu(1) + moveDiff, true, true, 10, moveSteps)
86+
87+ tryCompare(mouseEventSpy1, "count", moveSteps)
88+ var movedX = 0;
89+ var movedY = 0
90+ for (var i = 0; i < 5; i++) {
91+ movedX += mouseEventSpy1.signalArguments[i][0]
92+ movedY += mouseEventSpy1.signalArguments[i][1]
93+ }
94+ compare(movedX, moveDiff)
95+ compare(movedY, moveDiff)
96+ }
97+
98+ function test_doubleTapAndHoldToDrag() {
99+ mouseEventSpy1.signalName = "mousePressed"
100+ mouseEventSpy2.signalName = "mouseReleased"
101+
102+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
103+
104+ mouseClick(touchPadArea)
105+ mousePress(touchPadArea)
106+ mouseMove(touchPadArea, touchPadArea.width / 4, touchPadArea.height / 4)
107+
108+ tryCompare(mouseEventSpy1, "count", 1)
109+ tryCompare(mouseEventSpy2, "count", 0)
110+ mouseRelease(touchPadArea)
111+ tryCompare(mouseEventSpy2, "count", 1)
112+ }
113+
114+ function test_twoFingerScroll() {
115+ var touchPadArea = findChild(touchScreenPad, "touchPadArea");
116+
117+ mouseEventSpy1.signalName = "mouseScrolled"
118+
119+ var startX = touchPadArea.width / 2;
120+ var startY = touchPadArea.height / 2;
121+
122+ var startX1 = startX - units.gu(1);
123+ var startX2 = startX + units.gu(1);
124+
125+ var event = touchEvent(touchPadArea)
126+ event.press(0, startX1, startY)
127+ event.press(1, startX2, startY);
128+ event.commit()
129+
130+ for (var i = 0; i < 10; i++) {
131+ event.move(0, startX1, startY + units.gu(i))
132+ event.move(1, startX2, startY + units.gu(i));
133+ event.commit();
134+
135+ tryCompare(mouseEventSpy1, "count", i + 1);
136+ }
137+
138+ event.release(0, startX1, startY + units.gu(11))
139+ event.release(1, startX2, startY + units.gu(11));
140+ event.commit();
141+ }
142+ }
143+}
tests/qmltests/Components/tst_ZoomableImage.qml+8−5
@@ -73,7 +73,10 @@ Rectangle {
7373 tryCompareFunction(function() { return get_filename(imageRenderer.source.toString()) === get_filename(widgetData1["source"]); }, true);
7474 waitForRendering(zoomableImage);
7575 tryCompare(zoomableImage, "imageStatus", Image.Ready);
76− compare (signalSpy.count, 1);
76+ compare(signalSpy.count, 1);
77+ compare(imageRenderer.sourceSize.width, root.width);
78+ zoomableImage.zoomable = true;
79+ compare(imageRenderer.sourceSize.width, root.width*3);
7780 }
7881
7982 function get_filename(a) {
@@ -138,14 +141,14 @@ Rectangle {
138141 var imageRenderer = findChild(zoomableImage, "imageRenderer");
139142 var flickable = findChild(zoomableImage, "flickable");
140143
141− signalSpy.signalName = "onScaleChanged";
142− signalSpy.target = image;
143− signalSpy.clear();
144−
145144 zoomableImage.source = data.source;
146145 zoomableImage.zoomable = data.zoomable;
147146 waitForRendering(zoomableImage);
148147
148+ signalSpy.signalName = "onScaleChanged";
149+ signalSpy.target = image;
150+ signalSpy.clear();
151+
149152 tryCompare(zoomableImage, "imageStatus", Image.Ready);
150153 tryCompareFunction(function() { return get_filename(imageRenderer.source.toString()) === get_filename(data.source); }, true);
151154 waitForRendering(image);
tests/qmltests/Dash/CardHelpers.js+1−1
@@ -16,7 +16,7 @@
1616
1717.pragma library
1818
19−var components = ["title", "art", "subtitle", "mascot", "emblem", "summary", "attributes", "overlayColor"]
19+var components = ["title", "art", "subtitle", "mascot", "emblem", "summary", "attributes", "overlayColor", "quickPreviewData"]
2020
2121var defaultLayout = ' \
2222{ \
tests/qmltests/Dash/Previews/tst_Preview.qml+5−6
@@ -121,15 +121,14 @@ Rectangle {
121121 var moreLessButton = findChild(widget, "moreLessButton");
122122 mouseClick(moreLessButton);
123123
124− // Make sure the combo is growing
125− tryCompareFunction(function () { return widget.height > 2 * initialWidgetHeight; }, true);
126−
127124 // Wait for the combo to stop growing
128− tryCompareFunction(function () { var currentWidgetHeight = widget.height; wait(200); return currentWidgetHeight === widget.height;}, true);
125+ tryCompare(widget, "height", units.gu(15));
129126
130127 // Make sure the combo bottom is on the viewport
131− var bottomLeft = preview.mapFromItem(widget, 0, widget.height);
132− verify(bottomLeft.y <= preview.height);
128+ tryCompareFunction(function () {
129+ var bottomLeft = preview.mapFromItem(widget, 0, widget.height);
130+ return bottomLeft.y <= preview.height
131+ }, true);
133132 }
134133 }
135134}
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+16−11
@@ -18,6 +18,7 @@ import QtQuick 2.4
1818import QtTest 1.0
1919import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
21+import Dash 0.1
2122import Unity.Test 0.1 as UT
2223import QtMultimedia 5.0
2324
@@ -58,8 +59,8 @@ Rectangle {
5859 function test_time_formatter_data() {
5960 return [
6061 { tag: "NaN", value: "not a number", result: "" },
61− { tag: "0", value: 0, result: "" },
6262 { tag: "-1", value: -1, result: "" },
63+ { tag: "0", value: 0, result: "0:00" },
6364 { tag: "30", value: 30, result: "0:30" },
6465 { tag: "60", value: 60, result: "1:00" },
6566 { tag: "3600", value: 3600, result: "1:00:00" }
@@ -67,8 +68,7 @@ Rectangle {
6768 }
6869
6970 function test_time_formatter(data) {
70− var audio = findInvisibleChild(previewAudioPlayback, "audio");
71− compare(audio.lengthToString(data.value), data.result)
71+ compare(DashAudioPlayer.lengthToString(data.value), data.result)
7272 }
7373
7474 function test_tracks_data() {
@@ -100,13 +100,17 @@ Rectangle {
100100 }
101101 }
102102
103− function checkPlayerSource(index) {
104− var modelFilename = previewAudioPlayback.widgetData["tracks"][index]["source"].replace(/^.*[\\\/]/, '');
105− var playerFilename = findInvisibleChild(previewAudioPlayback, "audio").source.toString().replace(/^.*[\\\/]/, '');
103+ function checkPlayerUrls(modelFilename, playerUrl) {
104+ var modelFilename = modelFilename.replace(/^.*[\\\/]/, '');
105+ var playerFilename = playerUrl.toString().replace(/^.*[\\\/]/, '');
106106
107107 compare(modelFilename, playerFilename, "Player source is not set correctly.");
108108 }
109109
110+ function checkPlayerSource(index) {
111+ checkPlayerUrls(previewAudioPlayback.widgetData["tracks"][index]["source"], DashAudioPlayer.currentSource);
112+ }
113+
110114 function test_playback() {
111115 previewAudioPlayback.widgetData = tracksModel2;
112116 waitForRendering(previewAudioPlayback);
@@ -123,7 +127,7 @@ Rectangle {
123127 var track1PlayButton = findChild(track1Item, "playButton");
124128 var track2PlayButton = findChild(track2Item, "playButton");
125129
126− var audio = findInvisibleChild(previewAudioPlayback, "audio");
130+ var audio = DashAudioPlayer.audio;
127131
128132 // All progress bars must be hidden in the beginning
129133 compare(track0ProgressBar.visible, false);
@@ -157,6 +161,11 @@ Rectangle {
157161 tryCompare(audio, "playbackState", Audio.PlayingState);
158162 checkPlayerSource(1);
159163
164+ // Check the playlist is song 0, 1, 2
165+ checkPlayerUrls(tracksModel2["tracks"][0].source, audio.playlist.itemSource(0));
166+ checkPlayerUrls(tracksModel2["tracks"][1].source, audio.playlist.itemSource(1));
167+ checkPlayerUrls(tracksModel2["tracks"][2].source, audio.playlist.itemSource(2));
168+
160169 tryCompare(track0ProgressBar, "visible", false);
161170 tryCompare(track1ProgressBar, "visible", true);
162171 tryCompare(track2ProgressBar, "visible", false);
@@ -170,10 +179,6 @@ Rectangle {
170179 tryCompare(track0ProgressBar, "visible", false);
171180 tryCompare(track1ProgressBar, "visible", false);
172181 tryCompare(track2ProgressBar, "visible", true);
173−
174− // Changing preview should make all players shut up!
175− previewAudioPlayback.isCurrentPreview = false
176− tryCompare(audio, "playbackState", Audio.StoppedState);
177182 }
178183 }
179184}
tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+15
@@ -54,6 +54,14 @@ Rectangle {
5454 "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
5555 }
5656
57+ property var emptyfallbackheaderjson: {
58+ "title": "THE TITLE",
59+ "subtitle": "Something catchy",
60+ "mascot": "",
61+ "fallback": "../graphics/play_button.png",
62+ "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
63+ }
64+
5765 PreviewHeader {
5866 id: previewHeader
5967 widgetData: headerjson
@@ -150,6 +158,13 @@ Rectangle {
150158 var mascot = findChild(previewHeader, "mascotShape");
151159 tryCompare(mascot, "visible", true);
152160 tryCompare(mascot.source, "status", Image.Ready);
161+
162+ previewHeader.widgetData = {};
163+ previewHeader.widgetData = emptyfallbackheaderjson;
164+ tryCompareFunction(function() { return findChild(previewHeader, "mascotShape") != null }, true);
165+ var mascot = findChild(previewHeader, "mascotShape");
166+ tryCompare(mascot, "visible", true);
167+ tryCompare(mascot.source, "status", Image.Ready);
153168 }
154169 }
155170}
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+19
@@ -48,6 +48,16 @@ Rectangle {
4848 , "fallback": "../../../tests/graphics/clock@18.png"
4949 }
5050
51+ property var sourcesModelEmptyWithFallback: {
52+ "sources": [
53+ "../../graphics/phone_background.jpg",
54+ "../../graphics/tablet_background.jpg",
55+ "../../../tests/graphics/clock@18.png",
56+ ""
57+ ]
58+ , "fallback": "../../../tests/graphics/clock@18.png"
59+ }
60+
5161 PreviewImageGallery {
5262 id: imageGallery
5363 width: parent.width
@@ -123,5 +133,14 @@ Rectangle {
123133 image3 = findChild(imageGallery, "previewImage3");
124134 tryCompare(image3, "state", "ready");
125135 }
136+
137+ function test_empty_fallback() {
138+ var image3 = findChild(imageGallery, "previewImage3");
139+ tryCompare(image3, "state", "error");
140+ imageGallery.widgetData = sourcesModel0;
141+ imageGallery.widgetData = sourcesModelEmptyWithFallback;
142+ image3 = findChild(imageGallery, "previewImage3");
143+ tryCompare(image3, "state", "ready");
144+ }
126145 }
127146}
tests/qmltests/Dash/Previews/tst_PreviewMediaToolbar.qmlnew file+69
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtTest 1.0
19+import Ubuntu.Components 1.3
20+import "../../../../qml/Dash/Previews"
21+import Unity.Test 0.1 as UT
22+
23+Rectangle {
24+ id: root
25+ width: units.gu(40)
26+ height: units.gu(80)
27+ color: "black"
28+
29+ property var shareData: {
30+ "uri": [
31+ "Text here",
32+ "text here 2",
33+ "text here 3"
34+ ],
35+ "content-type": "text"
36+ }
37+
38+ property var shareDataNoUri: {
39+ "uri": "",
40+ "content-type": "text"
41+ }
42+
43+
44+ PreviewMediaToolbar {
45+ id: previewMediaToolbar
46+ anchors { left: parent.left; bottom: parent.bottom; }
47+ shareData: root.shareData
48+ }
49+
50+ UT.UnityTestCase {
51+ name: "PreviewMediaToolbarTest"
52+ when: windowShown
53+
54+ property Item sharingWidget: findChild(previewMediaToolbar, "sharingWidget")
55+
56+ function cleanup() {
57+ previewMediaToolbar.shareData = root.shareData;
58+ }
59+
60+ function test_visible() {
61+ previewMediaToolbar.shareData = shareDataNoUri;
62+ compare(previewMediaToolbar.visible, false);
63+ compare(sharingWidget.visible, false);
64+ previewMediaToolbar.shareData = shareData;
65+ compare(previewMediaToolbar.visible, true);
66+ compare(sharingWidget.visible, true);
67+ }
68+ }
69+}
tests/qmltests/Dash/Previews/tst_PreviewSharing.qml+1−13
@@ -32,12 +32,7 @@ Rectangle {
3232 "text here 2",
3333 "text here 3"
3434 ],
35− "contentType": "text"
36− }
37−
38− property var shareDataNoUri: {
39− "uri": "",
40− "contentType": "text"
35+ "content-type": "text"
4136 }
4237
4338 PreviewSharing {
@@ -54,13 +49,6 @@ Rectangle {
5449
5550 function cleanup() {
5651 peerPicker.visible = false;
57− previewSharing.shareData = root.shareData;
58− }
59−
60− function test_visible() {
61− compare(previewSharing.visible, true);
62− previewSharing.shareData = shareDataNoUri;
63− compare(previewSharing.visible, false);
6452 }
6553
6654 function test_open_picker() {
tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+12
@@ -39,6 +39,11 @@ Rectangle {
3939 "fallback": "../../graphics/phone_background.jpg"
4040 }
4141
42+ property var widgetData3: {
43+ "source": "",
44+ "fallback": "../../graphics/phone_background.jpg"
45+ }
46+
4247 Loader {
4348 id: loader
4449 width: parent.width
@@ -100,5 +105,12 @@ Rectangle {
100105 waitForRendering(lazyImage);
101106 tryCompare(lazyImage, "state", "ready");
102107 }
108+
109+ function test_emptyfallback() {
110+ zoomableImage.widgetData = widgetData3;
111+ waitForRendering(zoomableImage);
112+ waitForRendering(lazyImage);
113+ tryCompare(lazyImage, "state", "ready");
114+ }
103115 }
104116}
tests/qmltests/Dash/tst_Card.qml+30−7
@@ -35,7 +35,8 @@ Rectangle {
3535 "title": "foo",
3636 "subtitle": "bar",
3737 "summary": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
38− "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
38+ "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}],
39+ "quickPreviewData": {"uri": "/some/file", "duration": "14"}
3940 }'
4041
4142 property var cardsModel: [
@@ -106,6 +107,11 @@ Rectangle {
106107 "layout": { "template": { "card-layout": "horizontal" },
107108 "components": JSON.parse(Helpers.fullMapping) }
108109 },
110+ {
111+ "name": "Art, title, subtitle - Audio",
112+ "layout": { "template": { "card-layout": "horizontal", "quick-preview-type": "audio" },
113+ "components": { "art": "art", "title": "title", "subtitle": "subtitle", "quickPreviewData": "quickPreviewData" } }
114+ },
109115 ]
110116
111117 CardTool {
@@ -124,11 +130,11 @@ Rectangle {
124130 sourceComponent: cardTool.cardComponent
125131 clip: true
126132 onLoaded: {
127− item.components = Qt.binding(function() { return cardTool.components; });
128133 item.cardData = Qt.binding(function() { return Helpers.mapData(dataArea.text, cardTool.components, dataError); });
129134 item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
130135 item.height = Qt.binding(function() { return cardTool.cardHeight || item.implicitHeight; });
131136 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
137+ item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
132138 }
133139 }
134140
@@ -225,6 +231,7 @@ Rectangle {
225231 function init() {
226232 cardTool.components = Qt.binding(function() { return Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components']; });
227233 loader.visible = true;
234+ waitForRendering(card);
228235 }
229236
230237 function cleanup() {
@@ -299,8 +306,8 @@ Rectangle {
299306 { tag: "Medium", width: units.gu(18), fill: Image.PreserveAspectCrop, index: 0 },
300307 { tag: "Small", width: units.gu(12), index: 1 },
301308 { tag: "Large", width: units.gu(38), index: 2 },
302− { tag: "Wide", height: units.gu(19), size: "large", index: 3 },
303− { tag: "Tall", height: units.gu(38) / 0.7, size: "large", width: units.gu(38), index: 4 },
309+ { tag: "Wide", height: function() { return units.gu(19) }, size: "large", index: 3 },
310+ { tag: "Tall", height: function() { return units.gu(38) / 0.7 }, size: "large", width: units.gu(38), index: 4 },
304311 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) }, index: 0 },
305312 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
306313 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
@@ -329,9 +336,7 @@ Rectangle {
329336 }
330337
331338 if (data.hasOwnProperty("height")) {
332− if (typeof data.height === "function") {
333− tryCompareFunction(function() { return art.height === data.height() }, true);
334− } else tryCompare(art, "height", data.height);
339+ tryCompareFunction(function() { return art.height.toFixed(2) === data.height().toFixed(2) }, true);
335340 }
336341
337342 if (data.hasOwnProperty("fill")) {
@@ -470,6 +475,15 @@ Rectangle {
470475 card.cardDataChanged();
471476 waitForRendering(card);
472477 tryCompare(art, "visible", true);
478+ compare(artImage.source, Qt.resolvedUrl("artwork/emblem.png"));
479+
480+ cardTool.components["art"]["fallback"] = Qt.resolvedUrl("artwork/checkers.png");
481+ cardTool.componentsChanged();
482+ card.cardData["art"] = "";
483+ card.cardDataChanged();
484+ waitForRendering(card);
485+ tryCompare(art, "visible", true);
486+ compare(artImage.source, Qt.resolvedUrl("artwork/checkers.png"));
473487
474488 card.cardData["mascot"] = "somethingbroken2";
475489 card.cardDataChanged();
@@ -481,6 +495,15 @@ Rectangle {
481495 card.cardDataChanged();
482496 waitForRendering(card);
483497 tryCompare(mascotImage, "status", Image.Ready);
498+ compare(mascotImage.source, Qt.resolvedUrl("artwork/emblem.png"));
499+
500+ cardTool.components["mascot"] = {"fallback": Qt.resolvedUrl("artwork/checkers.png")};
501+ cardTool.componentsChanged();
502+ card.cardData["mascot"] = "";
503+ card.cardDataChanged();
504+ waitForRendering(card);
505+ tryCompare(mascotImage, "status", Image.Ready);
506+ compare(mascotImage.source, Qt.resolvedUrl("artwork/checkers.png"));
484507 }
485508
486509 function test_font_weights_data() {
tests/qmltests/Dash/tst_CardBenchmark.qml−2
@@ -61,8 +61,6 @@ Rectangle {
6161 item.width = Qt.binding(function() { return cardTool.cardWidth || implicitWidth; });
6262 item.height = Qt.binding(function() { return cardTool.cardHeight || implicitHeight; });
6363 item.cardData = Qt.binding(function() { return Helpers.mapData(root.cardData, cardTool.components); });
64− item.template = Qt.binding(function() { return cardTool.template; });
65− item.components = Qt.binding(function() { return cardTool.components; });
6664 }
6765 }
6866 }
tests/qmltests/Dash/tst_DashContent.qml+1−1
@@ -604,7 +604,7 @@ Item {
604604 {
605605 var dashContentList = findChild(dashContent, "dashContentList");
606606 var header = findChild(dashContentList.currentItem, "scopePageHeader")
607− var favoriteAction = findChild(header, "favorite_action_button");
607+ var favoriteAction = findChild(header, "favorite_button");
608608 compare(dashContentList.currentIndex, 0);
609609 compare(dashContentList.indexAt(dashContentList.width * 1.5, 0), 1);
610610 var nextScopeId = dashContentList.itemAt(dashContentList.width * 1.5, 0).item.scope.id;
tests/qmltests/Dash/tst_GenericScopeView.qml+30−9
@@ -107,11 +107,12 @@ Item {
107107 {
108108 var categoryListView = findChild(genericScopeView, "categoryListView");
109109 waitForRendering(categoryListView);
110− while (!categoryListView.atYEnd) {
111− mouseFlick(genericScopeView, genericScopeView.width/2, genericScopeView.height - units.gu(8),
112− genericScopeView.width/2, genericScopeView.y)
113− tryCompare(categoryListView, "moving", false);
114− }
110+ tryCompareFunction(function() {
111+ mouseFlick(genericScopeView, genericScopeView.width/2, genericScopeView.height - units.gu(8),
112+ genericScopeView.width/2, genericScopeView.y)
113+ tryCompare(categoryListView, "moving", false);
114+ return categoryListView.atYEnd;
115+ }, true);
115116 }
116117
117118 function test_isActive() {
@@ -238,7 +239,7 @@ Item {
238239
239240 openPreview(4, 0);
240241
241− compare(testCase.subPageLoader.count, 12, "There should only be 12 items in preview.");
242+ compare(testCase.subPageLoader.count, 16, "There should only be 16 items in preview.");
242243
243244 closePreview();
244245 }
@@ -413,7 +414,7 @@ Item {
413414 var previewListViewList = findChild(subPageLoader.item, "listView");
414415
415416 // flick to the next previews
416− tryCompare(testCase.subPageLoader, "count", 15);
417+ tryCompare(testCase.subPageLoader, "count", 25);
417418 for (var i = 1; i < testCase.subPageLoader.count; ++i) {
418419 mouseFlick(testCase.subPageLoader.item, testCase.subPageLoader.width - units.gu(1),
419420 testCase.subPageLoader.height / 2,
@@ -487,7 +488,7 @@ Item {
487488 mockScope.setName("Mock Scope");
488489 mockScope.categories.setCount(2);
489490 mockScope.categories.resultModel(0).setResultCount(50);
490− mockScope.categories.resultModel(1).setResultCount(15);
491+ mockScope.categories.resultModel(1).setResultCount(25);
491492 mockScope.categories.setLayout(0, "grid");
492493 mockScope.categories.setLayout(1, "grid");
493494 mockScope.categories.setHeaderLink(0, "");
@@ -529,7 +530,7 @@ Item {
529530 mockScope.setId("mockScope");
530531 mockScope.setName("Mock Scope");
531532 mockScope.categories.setCount(2);
532− mockScope.categories.resultModel(0).setResultCount(15);
533+ mockScope.categories.resultModel(0).setResultCount(25);
533534 mockScope.categories.resultModel(1).setResultCount(50);
534535 mockScope.categories.setLayout(0, "grid");
535536 mockScope.categories.setLayout(1, "grid");
@@ -666,6 +667,26 @@ Item {
666667 var shape = findChildsByType(artShapeLoader, "UCUbuntuShape");
667668 compare(shape.borderSource, undefined);
668669 }
670+
671+ function test_clickScopeSizing() {
672+ genericScopeView.scope = scopes.getScopeFromAll("clickscope");
673+ waitForRendering(genericScopeView);
674+
675+ var categoryListView = findChild(genericScopeView, "categoryListView");
676+ waitForRendering(categoryListView);
677+
678+ var categorypredefined = findChild(categoryListView, "dashCategorypredefined");
679+ waitForRendering(categorypredefined);
680+
681+ var cardTool = findChild(categorypredefined, "cardTool");
682+
683+ compare(cardTool.cardWidth, units.gu(11));
684+ shell.width = units.gu(46);
685+ waitForRendering(genericScopeView);
686+ compare(cardTool.cardWidth, units.gu(10));
687+
688+ shell.width = units.gu(120)
689+ }
669690 }
670691 }
671692}
tests/qmltests/Greeter/tst_Greeter.qml+39−3
@@ -71,9 +71,9 @@ Item {
7171 }
7272
7373 SignalSpy {
74− id: emergencyCallSpy
74+ id: activeChangedSpy
7575 target: loader.item
76− signalName: "emergencyCall"
76+ signalName: "activeChanged"
7777 }
7878
7979 GSettings {
@@ -142,7 +142,7 @@ Item {
142142 resetLoader();
143143 teaseSpy.clear();
144144 sessionStartedSpy.clear();
145− emergencyCallSpy.clear();
145+ activeChangedSpy.clear();
146146 viewShowMessageSpy.clear();
147147 viewShowPromptSpy.clear();
148148 viewShowLastChanceSpy.clear();
@@ -458,6 +458,20 @@ Item {
458458 compare(view.delayMinutes, greeter.failedLoginsDelayMinutes);
459459 }
460460
461+ function test_forcedDelayOnConstructionIgnoredIfInFuture() {
462+ greeterSettings.lockedOutTime = new Date().getTime() + greeter.failedLoginsDelayMinutes * 60000 + 1;
463+ resetLoader();
464+ view = findChild(greeter, "testView");
465+ compare(view.delayMinutes, 0);
466+ }
467+
468+ function test_forcedDelayOnConstructionIgnoredIfInPast() {
469+ greeterSettings.lockedOutTime = new Date().getTime() - greeter.failedLoginsDelayMinutes * 60000 - 1;
470+ resetLoader();
471+ view = findChild(greeter, "testView");
472+ compare(view.delayMinutes, 0);
473+ }
474+
461475 function test_forcedDelayRoundTrip() {
462476 greeter.failedLoginsDelayAttempts = 1;
463477 greeter.failedLoginsDelayMinutes = 0.001; // make delay very short
@@ -471,6 +485,28 @@ Item {
471485 tryCompare(view, "delayMinutes", 0);
472486 }
473487
488+ function test_activeIsConstantDuringLockedApp() {
489+ // Regression test for bug 1525981: if we flicker active state even
490+ // briefly, the mpt-server will allow access to the device's drive.
491+
492+ selectUser("has-password");
493+ verify(greeter.active);
494+
495+ // Test opening a locked app
496+ greeter.lockedApp = "test-app";
497+ greeter.notifyAppFocused("test-app");
498+ verify(greeter.hasLockedApp);
499+ verify(!greeter.shown);
500+
501+ // Test going back to greeter from that locked app
502+ LightDM.Greeter.showGreeter();
503+ verify(!greeter.hasLockedApp);
504+ verify(greeter.shown);
505+
506+ // Active state should never have changed
507+ compare(activeChangedSpy.count, 0);
508+ }
509+
474510 function test_dbusRequestAuthenticationUser() {
475511 selectUser("no-password");
476512 LightDM.Greeter.requestAuthenticationUser("has-password");
tests/qmltests/Greeter/tst_WideView.qml+11
@@ -522,5 +522,16 @@ Item {
522522
523523 tryCompare(loginList, "height", view.height);
524524 }
525+
526+ function test_alphanumeric() {
527+ var passwordInput = findChild(view, "passwordInput");
528+
529+ verify(view.alphanumeric);
530+ compare(passwordInput.inputMethodHints, Qt.ImhNone);
531+ view.alphanumeric = false;
532+ compare(passwordInput.inputMethodHints, Qt.ImhDigitsOnly);
533+ view.alphanumeric = true;
534+ compare(passwordInput.inputMethodHints, Qt.ImhNone);
535+ }
525536 }
526537}
tests/qmltests/Launcher/tst_Launcher.qml+42
@@ -159,6 +159,20 @@ Item {
159159 target: LauncherModel
160160 }
161161
162+ Item {
163+ id: fakeDismissTimer
164+ property bool running: false
165+ signal triggered
166+
167+ function stop() {
168+ running = false;
169+ }
170+
171+ function restart() {
172+ running = true;
173+ }
174+ }
175+
162176 UnityTestCase {
163177 id: testCase
164178 name: "Launcher"
@@ -177,6 +191,11 @@ Item {
177191 launcherLoader.active = true;
178192 }
179193 function init() {
194+ var panel = findChild(launcher, "launcherPanel");
195+ verify(!!panel);
196+
197+ panel.dismissTimer = fakeDismissTimer;
198+
180199 // Make sure we don't start the test with the mouse hovering the launcher
181200 mouseMove(root, root.width, root.height / 2);
182201
@@ -195,6 +214,8 @@ Item {
195214
196215 // Now do check that snapping is in fact enabled
197216 compare(listView.snapMode, ListView.SnapToItem, "Snapping is not enabled");
217+
218+ removeTimeConstraintsFromDirectionalDragAreas(root);
198219 }
199220
200221 function dragLauncherIntoView() {
@@ -625,6 +646,7 @@ Item {
625646 if(data.mouse) {
626647 mouseClick(root)
627648 } else {
649+ touchRelease(draggedItem)
628650 tap(root)
629651 }
630652
@@ -739,6 +761,21 @@ Item {
739761 mouseRelease(draggedItem);
740762 }
741763
764+ function test_launcher_dismiss() {
765+ dragLauncherIntoView();
766+ verify(launcher.state == "visible");
767+ mouseClick(root);
768+ waitUntilLauncherDisappears();
769+ verify(launcher.state == "");
770+
771+ // and repeat, as a test for regression in lpbug#1531339
772+ dragLauncherIntoView();
773+ verify(launcher.state == "visible");
774+ mouseClick(root);
775+ waitUntilLauncherDisappears();
776+ verify(launcher.state == "");
777+ }
778+
742779 function test_quicklist_positioning_data() {
743780 return [
744781 {tag: "top", flickTo: "top", itemIndex: 0},
@@ -879,6 +916,11 @@ Item {
879916 // Now move the mouse away and make sure it hides in less than a second
880917 mouseMove(root, root.width, root.height / 2)
881918
919+ // trigger the hide timer
920+ compare(fakeDismissTimer.running, true);
921+ fakeDismissTimer.triggered();
922+ tryCompare(panel, "x", 0);
923+
882924 tryCompare(launcher, "state", "", 1000, "Launcher didn't hide after moving mouse away from it");
883925 waitUntilLauncherDisappears();
884926 }
tests/qmltests/Panel/tst_IndicatorsMenu.qml+3−3
@@ -243,12 +243,12 @@ IndicatorTest {
243243
244244 // next time position will have moved.
245245 var nextItem = get_indicator_item(1);
246− var nextItemMappedPosition = root.mapFromItem(nextItem, nextItem.width/2, nextItem.height/2);
246+ var nextItemMappedPositionX = firstItemMappedPosition.x + firstItem.width;
247247
248248 // 1) Flick mouse down to bottom
249249 touchFlick(indicatorsMenu,
250250 firstItemMappedPosition.x, indicatorsMenu.minimizedPanelHeight * 2,
251− nextItemMappedPosition.x, indicatorsMenu.openedHeight / 3,
251+ nextItemMappedPositionX, indicatorsMenu.openedHeight / 3,
252252 false /* beginTouch */, false /* endTouch */,
253253 units.gu(50) /* speed */, 5 /* iterations */); // more samples needed for accurate velocity
254254
@@ -256,7 +256,7 @@ IndicatorTest {
256256 // after waiting in the same spot with touch down, it should update to the next item.
257257 tryCompare(indicatorItemRow, "currentItem", nextItem);
258258
259− touchRelease(indicatorsMenu, nextItemMappedPosition.x, indicatorsMenu.openedHeight / 3);
259+ touchRelease(indicatorsMenu, nextItemMappedPositionX, indicatorsMenu.openedHeight / 3);
260260 }
261261 }
262262}
tests/qmltests/Stages/RecursingChildSessionControl.qml+3−3
@@ -88,7 +88,7 @@ ColumnLayout {
8888
8989 CheckBox {
9090 id: _surfaceCheckbox;
91− checked: false;
91+ checked: root.session.lastSurface ? true : false
9292 activeFocusOnPress: false
9393 enabled: root.session
9494 onCheckedChanged: {
@@ -101,7 +101,7 @@ ColumnLayout {
101101
102102 Connections {
103103 target: root.session ? root.session : null
104− onSurfaceChanged: {
104+ onLastSurfaceChanged: {
105105 surfaceCheckbox.checked = root.session.lastSurface !== null
106106 }
107107 }
@@ -137,7 +137,7 @@ ColumnLayout {
137137 text: "Add Child"
138138 onClicked: {
139139 var screenshot = Math.round(Math.random()*100 % (screenshotIds.length-1));
140− var session = ApplicationTest.addChildSession(root.session, root.screenshotIds[screenshot]);
140+ var session = ApplicationTest.addChildSession(root.session, root.screenshotIds[screenshot], true);
141141 }
142142 }
143143 }
tests/qmltests/Stages/SizeHintField.qmlnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 1.3
20+
21+Row {
22+ property alias text: label.text
23+ property alias value: field.text
24+ spacing: units.gu(1)
25+ Label {
26+ id: label
27+ color: "black"; anchors.verticalCenter: parent.verticalCenter
28+ }
29+ TextField {
30+ id: field
31+ text: ""; width: units.gu(8); hasClearButton: false; maximumLength: 6; inputMask: "d00000"
32+ }
33+}
tests/qmltests/Stages/SurfaceManagerControls.qmlnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Unity.Application 0.1
20+
21+Column {
22+ id: root
23+ property color textColor: "black"
24+
25+ Label {text: "Size hints for new surface:"; color: root.textColor; font.bold: true}
26+
27+ SurfaceManagerField { text: "min width"; propertyName: "newSurfaceMinimumWidth"; textColor: root.textColor }
28+ SurfaceManagerField { text: "max width"; propertyName: "newSurfaceMaximumWidth"; textColor: root.textColor }
29+ SurfaceManagerField { text: "min height"; propertyName: "newSurfaceMinimumHeight"; textColor: root.textColor }
30+ SurfaceManagerField { text: "max height"; propertyName: "newSurfaceMaximumHeight"; textColor: root.textColor }
31+ SurfaceManagerField { text: "width increment"; propertyName: "newSurfaceWidthIncrement"; textColor: root.textColor }
32+ SurfaceManagerField { text: "height increment"; propertyName: "newSurfaceHeightIncrement"; textColor: root.textColor }
33+}
tests/qmltests/Stages/SurfaceManagerField.qmlnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Unity.Application 0.1
20+
21+Row {
22+ id: root
23+ property alias textColor: label.color
24+ property alias text: label.text
25+ property string propertyName
26+
27+ Label {id: label; anchors.verticalCenter: parent.verticalCenter}
28+ TextField {
29+ width: units.gu(10); hasClearButton: false; maximumLength: 6
30+ inputMask: "d00000"
31+ text: ""
32+ onTextChanged: {
33+ if (text.length > 0) {
34+ SurfaceManager[root.propertyName] = parseInt(text);
35+ } else {
36+ SurfaceManager[root.propertyName] = 0;
37+ }
38+ }
39+ }
40+}
tests/qmltests/Stages/tst_DesktopStage.qml+59−24
@@ -25,6 +25,7 @@ import Utils 0.1
2525import ".." // For EdgeBarrierControls
2626import "../../../qml/Stages"
2727import "../../../qml/Components"
28+import "../../../qml/Components/PanelState"
2829
2930Item {
3031 id: root
@@ -88,36 +89,42 @@ Item {
8889 right: parent.right
8990 }
9091
91− Column {
92− anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
93− spacing: units.gu(1)
94−
95− Button {
96− color: "white"
97− text: "Make surface slow to resize"
98− activeFocusOnPress: false
99− onClicked: {
100− if (ApplicationManager.focusedApplicationId) {
101− var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.lastSurface;
102− surface.slowToResize = true;
92+ Flickable {
93+ anchors.fill: parent
94+ contentHeight: controlsColumn.height
95+ Column {
96+ id: controlsColumn
97+ spacing: units.gu(1)
98+
99+ Button {
100+ color: "white"
101+ text: "Make surface slow to resize"
102+ activeFocusOnPress: false
103+ onClicked: {
104+ if (ApplicationManager.focusedApplicationId) {
105+ var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.lastSurface;
106+ surface.slowToResize = true;
107+ }
103108 }
104109 }
105− }
106110
107− EdgeBarrierControls {
108− id: edgeBarrierControls
109− text: "Drag here to pull out spread"
110− backgroundColor: "blue"
111− onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
112− }
111+ EdgeBarrierControls {
112+ id: edgeBarrierControls
113+ text: "Drag here to pull out spread"
114+ backgroundColor: "blue"
115+ onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
116+ }
113117
114− Divider {}
118+ Divider {}
115119
116− Repeater {
117− model: ApplicationManager.availableApplications
118− ApplicationCheckBox {
119− appId: modelData
120+ Repeater {
121+ model: ApplicationManager.availableApplications
122+ ApplicationCheckBox {
123+ appId: modelData
124+ }
120125 }
126+
127+ SurfaceManagerControls { textColor: "white" }
121128 }
122129 }
123130 }
@@ -500,5 +507,33 @@ Item {
500507 tryCompare(dialerAppDelegate, "visible", true);
501508 tryCompare(facebookAppDelegate, "visible", false);
502509 }
510+
511+ function test_dropShadow() {
512+ killAllRunningApps();
513+
514+ // verify the drop shadow is not visible initially
515+ verify(PanelState.dropShadow == false);
516+
517+ // start an app, maximize it
518+ var facebookApp = startApplication("facebook-webapp");
519+ var facebookAppDelegate = findChild(desktopStage, "appDelegate_facebook-webapp");
520+ facebookAppDelegate.maximize();
521+
522+ // verify the drop shadow is still not visible
523+ verify(PanelState.dropShadow == false);
524+
525+ // start a foreground app, not maximized
526+ var dialerApp = startApplication("dialer-app");
527+ var dialerAppDelegate = findChild(desktopStage, "appDelegate_dialer-app");
528+
529+ // verify the drop shadow becomes visible
530+ verify(PanelState.dropShadow == true);
531+
532+ // close the maximized app
533+ ApplicationManager.stopApplication("facebook-webapp");
534+
535+ // verify the drop shadow is gone
536+ verify(PanelState.dropShadow == false);
537+ }
503538 }
504539}
tests/qmltests/Stages/tst_SessionContainer.qml+27−5
@@ -155,7 +155,8 @@ Rectangle {
155155 var sessions = [];
156156 for (i = 0; i < data.count; i++) {
157157 var session = ApplicationTest.addChildSession(sessionContainer.session,
158− "gallery");
158+ "gallery",
159+ true);
159160 session.createSurface();
160161 sessionContainer.session.addChildSession(session);
161162 compare(sessionContainer.childSessions.count(), i+1);
@@ -180,7 +181,7 @@ Rectangle {
180181 // 3 sessions should cover all edge cases
181182 for(i = 0; i < 3; i++) {
182183 var a_session = ApplicationTest.addChildSession(
183− sessionContainer.session, "gallery"
184+ sessionContainer.session, "gallery", true
184185 )
185186
186187 a_session.createSurface();
@@ -226,7 +227,8 @@ Rectangle {
226227 var container = sessionContainer;
227228 for (i = 0; i < data.depth; i++) {
228229 var session = ApplicationTest.addChildSession(lastSession,
229− "gallery");
230+ "gallery",
231+ true);
230232 session.createSurface();
231233 lastSession.addChildSession(session);
232234 compare(container.childSessions.count(), 1);
@@ -250,7 +252,8 @@ Rectangle {
250252 var sessionContainer = sessionContainerLoader.item;
251253
252254 var session = ApplicationTest.addChildSession(sessionContainer.session,
253− "gallery");
255+ "gallery",
256+ true);
254257 session.createSurface();
255258 sessionContainer.session.addChildSession(session);
256259
@@ -288,7 +291,8 @@ Rectangle {
288291 var sessionContainer = sessionContainerLoader.item;
289292
290293 var session = ApplicationTest.addChildSession(sessionContainer.session,
291− "gallery");
294+ "gallery",
295+ true);
292296
293297 var delegate = findChild(sessionContainer, "childDelegate0");
294298 var childContainer = findChild(delegate, "sessionContainer");
@@ -304,6 +308,24 @@ Rectangle {
304308 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, true);
305309 // wait for animation to end
306310 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
311+
312+ tryCompareFunction(function() { return sessionContainer.childSessions.count() }, 0);
313+ }
314+
315+ function test_childSessionsRemovedOnStopWhenNotLive() {
316+ sessionCheckbox.checked = true;
317+ var sessionContainer = sessionContainerLoader.item;
318+
319+ var session = ApplicationTest.addChildSession(sessionContainer.session,
320+ "gallery",
321+ false);
322+
323+ var delegate = findChild(sessionContainer, "childDelegate0");
324+ var childContainer = findChild(delegate, "sessionContainer");
325+
326+ ApplicationTest.removeSession(session);
327+
328+ tryCompareFunction(function() { return sessionContainer.childSessions.count() }, 0);
307329 }
308330 }
309331}
tests/qmltests/Stages/tst_WindowResizeArea.qml+225−30
@@ -28,7 +28,7 @@ import Unity.Application 0.1
2828Item {
2929 id: root
3030 height: units.gu(60)
31− width: units.gu(60)
31+ width: units.gu(85)
3232
3333 Binding {
3434 target: PanelState
@@ -41,14 +41,20 @@ Item {
4141
4242 Item {
4343 id: fakeWindow
44− property alias minWidth: windowResizeArea.minWidth
45− property alias minHeight: windowResizeArea.minHeight
44+ property alias resizeAreaMinWidth: windowResizeArea.minWidth
45+ property alias resizeAreaMinHeight: windowResizeArea.minHeight
4646 x: units.gu(20)
4747 y: units.gu(20)
4848 width: requestedWidth
4949 height: requestedHeight
5050 property real requestedWidth
5151 property real requestedHeight
52+ property real minimumWidth: 0
53+ property real minimumHeight: 0
54+ property real maximumWidth: 0
55+ property real maximumHeight: 0
56+ property real widthIncrement: 0
57+ property real heightIncrement: 0
5258 state: "normal"
5359
5460 function maximize() {
@@ -80,6 +86,10 @@ Item {
8086 anchors.fill: parent
8187 hoverEnabled: true
8288 }
89+ Text {
90+ text: parent.width + "x" + parent.height
91+ color: "white"
92+ }
8393 }
8494 }
8595 }
@@ -90,27 +100,107 @@ Item {
90100 active: windowLoaderCheckbox.checked
91101 }
92102
93− Column {
94− MouseTouchEmulationCheckbox {
95− checked: false
96− color: "black"
97− }
98− RowLayout {
99− Layout.fillWidth: true
100− CheckBox {
101− id: windowLoaderCheckbox
102− checked: true
103− activeFocusOnPress: false
103+ Rectangle {
104+ anchors.right: parent.right
105+ anchors.top: parent.top
106+ anchors.bottom: parent.bottom
107+ width: units.gu(25)
108+ color: "lightgrey"
109+ Column {
110+ width: parent.width
111+ spacing: units.gu(1)
112+ MouseTouchEmulationCheckbox {
113+ checked: false
114+ color: "black"
115+ }
116+ RowLayout {
117+ Layout.fillWidth: true
118+ CheckBox {
119+ id: windowLoaderCheckbox
120+ checked: true
121+ activeFocusOnPress: false
122+ }
123+ Label {
124+ color: "black"
125+ text: "Window loader active"
126+ anchors.verticalCenter: parent.verticalCenter
127+ }
104128 }
105129 Label {
106− id: label
130+ color: "black"; font.bold: true
131+ text: "Size Hints:"
132+ }
133+ SizeHintField { id: minWidthText; text: "min width" }
134+ SizeHintField { id: maxWidthText; text: "max width" }
135+ SizeHintField { id: minHeightText; text: "min height" }
136+ SizeHintField { id: maxHeightText; text: "max height" }
137+ SizeHintField { id: widthIncrText; text: "width incr" }
138+ SizeHintField { id: heightIncrText; text: "height incr" }
139+ Button {
107140 color: "black"
108− text: "Window loader active"
109− anchors.verticalCenter: parent.verticalCenter
141+ anchors.horizontalCenter: parent.horizontalCenter
142+ text: "Apply"
143+ onClicked: {
144+ var value = parseInt(minWidthText.value);
145+ if (isNaN(value)) {
146+ windowLoader.item.minimumWidth = 0;
147+ } else {
148+ windowLoader.item.resizeAreaMinWidth = 1; // get it out of the way
149+ windowLoader.item.minimumWidth = value;
150+ }
151+
152+ value = parseInt(maxWidthText.value);
153+ if (isNaN(value)) {
154+ windowLoader.item.maximumWidth = 0;
155+ } else {
156+ windowLoader.item.maximumWidth = value;
157+ }
158+
159+ value = parseInt(minHeightText.value);
160+ if (isNaN(value)) {
161+ windowLoader.item.minimumHeight = 0;
162+ } else {
163+ windowLoader.item.resizeAreaMinHeight = 1; // get it out of the way
164+ windowLoader.item.minimumHeight = value;
165+ }
166+
167+ value = parseInt(maxHeightText.value);
168+ if (isNaN(value)) {
169+ windowLoader.item.maximumHeight = 0;
170+ } else {
171+ windowLoader.item.maximumHeight = value;
172+ }
173+
174+ value = parseInt(widthIncrText.value);
175+ if (isNaN(value)) {
176+ windowLoader.item.widthIncrement = 0;
177+ } else {
178+ windowLoader.item.widthIncrement = value;
179+ }
180+
181+ value = parseInt(heightIncrText.value);
182+ if (isNaN(value)) {
183+ windowLoader.item.heightIncrement = 0;
184+ } else {
185+ windowLoader.item.heightIncrement = value;
186+ }
187+ }
110188 }
111189 }
112190 }
113191
192+ SignalSpy {
193+ id: windowRequestedWidthSpy
194+ target: windowLoader.item
195+ signalName: "onRequestedWidthChanged"
196+ }
197+
198+ SignalSpy {
199+ id: windowRequestedHeightSpy
200+ target: windowLoader.item
201+ signalName: "onRequestedHeightChanged"
202+ }
203+
114204 UnityTestCase {
115205 name: "WindowResizeArea"
116206 when: windowShown
@@ -122,6 +212,18 @@ Item {
122212 fakeWindow.y = units.gu(20)
123213 fakeWindow.requestedWidth = units.gu(20)
124214 fakeWindow.requestedHeight = units.gu(20)
215+ fakeWindow.resizeAreaMinWidth = units.gu(15);
216+ fakeWindow.resizeAreaMinHeight = units.gu(10);
217+ fakeWindow.minimumWidth = 0;
218+ fakeWindow.minimumHeight = 0;
219+ fakeWindow.maximumWidth = 0;
220+ fakeWindow.maximumHeight = 0;
221+ fakeWindow.widthIncrement = 0;
222+ fakeWindow.heightIncrement = 0;
223+
224+ // Our test window resizes instantly
225+ compare(fakeWindow.width, fakeWindow.requestedWidth);
226+ compare(fakeWindow.height, fakeWindow.requestedHeight);
125227 }
126228
127229 function test_resizeWindowRightBottom_data() {
@@ -143,8 +245,8 @@ Item {
143245 var startDragY = initialWindowY + initialWindowHeight + 1
144246 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
145247
146− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.minWidth));
147− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.minHeight));
248+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.resizeAreaMinWidth));
249+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.resizeAreaMinHeight));
148250
149251 compare(fakeWindow.x, initialWindowX);
150252 compare(fakeWindow.y, initialWindowY);
@@ -169,11 +271,11 @@ Item {
169271 var startDragY = initialWindowY - 1
170272 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
171273
172− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.minWidth));
173− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.minHeight));
274+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.resizeAreaMinWidth));
275+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.resizeAreaMinHeight));
174276
175− var maxMoveX = initialWindowWidth - fakeWindow.minWidth;
176− var maxMoveY = initialWindowHeight - fakeWindow.minHeight;
277+ var maxMoveX = initialWindowWidth - fakeWindow.resizeAreaMinWidth;
278+ var maxMoveY = initialWindowHeight - fakeWindow.resizeAreaMinHeight;
177279 compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
178280 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
179281 }
@@ -189,8 +291,8 @@ Item {
189291 var startDragY = initialWindowY + initialWindowHeight + 1
190292 mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
191293
192− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
193− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
294+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
295+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
194296
195297 // This will destroy the window and recreate it
196298 windowLoader.active = false;
@@ -198,8 +300,8 @@ Item {
198300 windowLoader.active = true;
199301
200302 // Make sure its size is again the same as before
201− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
202− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
303+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
304+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
203305 }
204306
205307 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
@@ -220,8 +322,8 @@ Item {
220322 var startDragX = initialWindowX + data.startX
221323 var startDragY = initialWindowY + data.startY
222324 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
223− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.minWidth));
224− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.minHeight));
325+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.resizeAreaMinWidth));
326+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.resizeAreaMinHeight));
225327 mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
226328 tryCompare(fakeWindow, "width", initialWindowWidth);
227329 tryCompare(fakeWindow, "height", initialWindowHeight);
@@ -257,7 +359,6 @@ Item {
257359 fakeWindow.state = "normal"
258360 }
259361
260−
261362 function test_restoreMovesIntoBounds_data() {
262363 return [
263364 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},
@@ -290,5 +391,99 @@ Item {
290391
291392 waitForRendering(root)
292393 }
394+
395+ /*
396+ Tests that even though you dragged the window bottom right corner continously (ie,
397+ through multiple intermediate steps), its (requested) width and height changed only
398+ once. And, furthermore, its dimensions increased by a multiple of its size (width
399+ and height) increment value.
400+ */
401+ function test_sizeIncrement() {
402+ var initialWindowX = fakeWindow.x;
403+ var initialWindowY = fakeWindow.y;
404+ var initialWindowWidth = fakeWindow.width
405+ var initialWindowHeight = fakeWindow.height
406+
407+ fakeWindow.widthIncrement = 70;
408+ fakeWindow.heightIncrement = 70;
409+
410+ var startDragX = initialWindowX + initialWindowWidth + 1
411+ var startDragY = initialWindowY + initialWindowHeight + 1
412+ var deltaX = 100;
413+ var deltaY = 100;
414+
415+ windowRequestedWidthSpy.clear();
416+ verify(windowRequestedWidthSpy.valid);
417+
418+ windowRequestedHeightSpy.clear();
419+ verify(windowRequestedHeightSpy.valid);
420+
421+ mouseFlick(root, startDragX, startDragY, startDragX + deltaX, startDragY + deltaY, true, true, units.gu(.5), 10);
422+
423+ compare(windowRequestedWidthSpy.count, 1);
424+ compare(fakeWindow.width, initialWindowWidth + fakeWindow.widthIncrement);
425+ compare(windowRequestedHeightSpy.count, 1);
426+ compare(fakeWindow.height, initialWindowHeight + fakeWindow.heightIncrement);
427+ }
428+
429+ /*
430+ Tests that when dragging a window border you cannot make it bigger than its maximum size
431+ */
432+ function test_maximumSize() {
433+ fakeWindow.x = units.gu(1);
434+ fakeWindow.y = units.gu(1);
435+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
436+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
437+ fakeWindow.requestedWidth = units.gu(10);
438+ fakeWindow.requestedHeight = units.gu(10);
439+
440+ fakeWindow.maximumWidth = units.gu(20);
441+ fakeWindow.maximumHeight = units.gu(20);
442+
443+ // Our test window resizes instantly
444+ compare(fakeWindow.width, fakeWindow.requestedWidth);
445+ compare(fakeWindow.height, fakeWindow.requestedHeight);
446+
447+ var startDragX = fakeWindow.width + 1
448+ var startDragY = fakeWindow.height + 1
449+ var endDragX = (fakeWindow.maximumWidth * 2) + 1;
450+ var endDragY = (fakeWindow.maximumHeight * 2) + 1;
451+
452+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
453+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
454+
455+ compare(fakeWindow.requestedWidth, fakeWindow.maximumWidth);
456+ compare(fakeWindow.requestedHeight, fakeWindow.maximumHeight);
457+ }
458+
459+ /*
460+ Tests that when dragging a window border you cannot make it smaller than its minimum size
461+ */
462+ function test_minimumSize() {
463+ fakeWindow.x = units.gu(1);
464+ fakeWindow.y = units.gu(1);
465+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
466+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
467+ fakeWindow.requestedWidth = units.gu(20);
468+ fakeWindow.requestedHeight = units.gu(20);
469+
470+ fakeWindow.minimumWidth = units.gu(10);
471+ fakeWindow.minimumHeight = units.gu(10);
472+
473+ // Our test window resizes instantly
474+ compare(fakeWindow.width, fakeWindow.requestedWidth);
475+ compare(fakeWindow.height, fakeWindow.requestedHeight);
476+
477+ var startDragX = fakeWindow.width + 1
478+ var startDragY = fakeWindow.height + 1
479+ var endDragX = (fakeWindow.minimumWidth * 0.5) + 1;
480+ var endDragY = (fakeWindow.minimumHeight * 0.5) + 1;
481+
482+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
483+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
484+
485+ compare(fakeWindow.requestedWidth, fakeWindow.minimumWidth);
486+ compare(fakeWindow.requestedHeight, fakeWindow.minimumHeight);
487+ }
293488 }
294489}
tests/qmltests/Wizard/tst_Wizard.qml+15
@@ -129,6 +129,7 @@ Item {
129129
130130 var pages = findChild(wizard, "wizardPages");
131131 var security = findInvisibleChild(pages, "securityPrivacy");
132+ security.setSecurity("", "", UbuntuSecurityPrivacyPanel.Swipe);
132133 setSecuritySpy.target = security;
133134
134135 setup();
@@ -315,6 +316,20 @@ Item {
315316 }
316317 }
317318
319+ function test_passwdSkipIfSet() {
320+ var page = goToPage("simPage");
321+
322+ // Set password type to non-swipe
323+ var pages = findChild(wizard, "wizardPages");
324+ var security = findInvisibleChild(pages, "securityPrivacy");
325+ security.setSecurity("", "", UbuntuSecurityPrivacyPanel.Passphrase);
326+ compare(security.securityType, UbuntuSecurityPrivacyPanel.Passphrase);
327+
328+ // Make sure that moving from sim page lands on wifi page
329+ tap(findChild(page, "forwardButton"));
330+ waitForPage("wifiPage"); // thus skipping passwdPage
331+ }
332+
318333 function test_passwdPasscode() {
319334 var page = goToPage("passwdPage");
320335
tests/qmltests/tst_DisabledScreenNotice.qml+10−2
@@ -19,13 +19,13 @@ import QtTest 1.0
1919import Unity.Test 0.1
2020import "../../qml"
2121
22−
2322Item {
2423 id: root
25− width: units.gu(70)
24+ width: units.gu(40)
2625 height: units.gu(70)
2726
2827 DisabledScreenNotice {
28+ id: touchScreenPad
2929 anchors.fill: parent
3030 }
3131
@@ -33,5 +33,13 @@ Item {
3333 id: testCase
3434 name: "DisabledScreenNotice"
3535 when: windowShown
36+
37+ function test_mouseAreaHidesOnFirstTap() {
38+ var noticeArea = findChild(touchScreenPad, "infoNoticeArea")
39+ print("noticeArea", noticeArea.visible)
40+ compare(noticeArea.visible, true)
41+ tap(root)
42+ tryCompare(noticeArea, "visible", false)
43+ }
3644 }
3745}
tests/qmltests/tst_OrientedShell.qml+107−23
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@ import Ubuntu.Components 1.3
2121import Ubuntu.Components.ListItems 1.3 as ListItem
2222import Unity.Application 0.1
2323import Unity.Test 0.1
24−import LightDM.IntegratedLightDM 0.1 as LightDM
24+import IntegratedLightDM 0.1 as LightDM
2525import Powerd 0.1
2626import Unity.InputInfo 0.1
2727
@@ -292,6 +292,9 @@ Rectangle {
292292 activeFocusOnPress: false
293293 text: "Usage Mode"
294294 model: ["Staged", "Windowed", "Automatic"]
295+ function selectStaged() {selectedIndex = 0;}
296+ function selectWindowed() {selectedIndex = 1;}
297+ function selectAutomatic() {selectedIndex = 2;}
295298 }
296299 MouseTouchEmulationCheckbox {
297300 checked: true
@@ -393,7 +396,7 @@ Rectangle {
393396 activeFocusOnPress: false
394397 property string prevDevName: "mako"
395398 onClicked: {
396− usageModeSelector.selectedIndex = 2; // "Automatic"
399+ usageModeSelector.selectAutomatic();
397400
398401 if (applicationArguments.deviceName === "desktop") {
399402 applicationArguments.deviceName = prevDevName;
@@ -457,6 +460,8 @@ Rectangle {
457460 signalSpy.signalName = "";
458461
459462 LightDM.Greeter.authenticate(""); // reset greeter
463+
464+ usageModeSelector.selectStaged();
460465 }
461466
462467 function cleanup() {
@@ -996,37 +1001,58 @@ Rectangle {
9961001 tryCompare(shell, "transformRotationAngle", 0);
9971002 }
9981003
999− function test_attachRemoveInputDevices() {
1000− usageModeSelector.selectedIndex = 2;
1004+ function test_attachRemoveInputDevices_data() {
1005+ return [
1006+ { tag: "small screen, no devices", screenWidth: units.gu(50), mouse: false, kbd: false, expectedMode: "phone", oskExpected: true },
1007+ { tag: "medium screen, no devices", screenWidth: units.gu(100), mouse: false, kbd: false, expectedMode: "phone", oskExpected: true },
1008+ { tag: "big screen, no devices", screenWidth: units.gu(200), mouse: false, kbd: false, expectedMode: "phone", oskExpected: true },
1009+ { tag: "small screen, mouse", screenWidth: units.gu(50), mouse: true, kbd: false, expectedMode: "phone", oskExpected: true },
1010+ { tag: "medium screen, mouse", screenWidth: units.gu(100), mouse: true, kbd: false, expectedMode: "desktop", oskExpected: true },
1011+ { tag: "big screen, mouse", screenWidth: units.gu(200), mouse: true, kbd: false, expectedMode: "desktop", oskExpected: true },
1012+ { tag: "small screen, kbd", screenWidth: units.gu(50), mouse: false, kbd: true, expectedMode: "phone", oskExpected: false },
1013+ { tag: "medium screen, kbd", screenWidth: units.gu(100), mouse: false, kbd: true, expectedMode: "phone", oskExpected: false },
1014+ { tag: "big screen, kbd", screenWidth: units.gu(200), mouse: false, kbd: true, expectedMode: "desktop", oskExpected: false },
1015+ { tag: "small screen, mouse & kbd", screenWidth: units.gu(50), mouse: true, kbd: true, expectedMode: "phone", oskExpected: false },
1016+ { tag: "medium screen, mouse & kbd", screenWidth: units.gu(100), mouse: true, kbd: true, expectedMode: "desktop", oskExpected: false },
1017+ { tag: "big screen, mouse & kbd", screenWidth: units.gu(200), mouse: true, kbd: true, expectedMode: "desktop", oskExpected: false },
1018+ ]
1019+ }
1020+
1021+ function test_attachRemoveInputDevices(data) {
1022+ usageModeSelector.selectAutomatic();
10011023 tryCompare(mockUnity8Settings, "usageMode", "Automatic")
10021024
10031025 loadShell("mako")
10041026 var shell = findChild(orientedShell, "shell");
1027+ var inputMethod = findChild(shell, "inputMethod");
10051028
1006− tryCompare(shell, "usageScenario", "phone");
1007− tryCompare(mockOskSettings, "stayHidden", false);
1029+ var oldWidth = orientedShellLoader.width;
1030+ orientedShellLoader.width = data.screenWidth;
10081031
1009− MockInputDeviceBackend.addMockDevice("/kbd0", InputInfo.Keyboard);
10101032 tryCompare(shell, "usageScenario", "phone");
1011− tryCompare(mockOskSettings, "stayHidden", true);
1012−
1013− MockInputDeviceBackend.addMockDevice("/mouse0", InputInfo.Mouse);
1014− tryCompare(shell, "usageScenario", "desktop");
1015− tryCompare(mockOskSettings, "stayHidden", true);
1033+ tryCompare(inputMethod, "enabled", true);
1034+ tryCompare(mockOskSettings, "disableHeight", false);
10161035
1017− MockInputDeviceBackend.removeDevice("/kbd0");
1018− tryCompare(shell, "usageScenario", "desktop");
1019− tryCompare(mockOskSettings, "stayHidden", false);
1036+ if (data.kbd) {
1037+ MockInputDeviceBackend.addMockDevice("/kbd0", InputInfo.Keyboard);
1038+ }
1039+ if (data.mouse) {
1040+ MockInputDeviceBackend.addMockDevice("/mouse0", InputInfo.Mouse);
1041+ }
10201042
1021− MockInputDeviceBackend.removeDevice("/mouse0");
1022− tryCompare(shell, "usageScenario", "phone");
1023− tryCompare(mockOskSettings, "stayHidden", false);
1043+ tryCompare(shell, "usageScenario", data.expectedMode);
1044+ tryCompare(inputMethod, "enabled", data.oskExpected);
1045+ tryCompare(mockOskSettings, "disableHeight", data.expectedMode == "desktop" || data.kbd);
10241046
1025− MockInputDeviceBackend.addMockDevice("/touchpad0", InputInfo.TouchPad);
1026− tryCompare(shell, "usageScenario", "desktop");
1047+ if (data.kbd) {
1048+ MockInputDeviceBackend.removeDevice("/kbd0");
1049+ }
1050+ if (data.mouse) {
1051+ MockInputDeviceBackend.removeDevice("/mouse0");
1052+ }
10271053
1028− MockInputDeviceBackend.removeDevice("/touchpad0");
1029− tryCompare(shell, "usageScenario", "phone");
1054+ // Restore width
1055+ orientedShellLoader.width = oldWidth;
10301056 }
10311057
10321058 /*
@@ -1140,6 +1166,61 @@ Rectangle {
11401166 tryCompare(shell, "transformRotationAngle" , 0);
11411167 }
11421168
1169+ /*
1170+ Regression test for https://launchpad.net/bugs/1515977
1171+
1172+ Preconditions:
1173+ UI in Desktop mode and landscape
1174+
1175+ Steps:
1176+ - Launch a portrait-only application
1177+
1178+ Expected outcome:
1179+ - Shell stays in landscape
1180+
1181+ Buggy outcome:
1182+ - Shell would rotate to portrait as the newly-focused app doesn't support landscape
1183+ */
1184+ function test_portraitOnlyAppInLandscapeDesktop_data() {
1185+ return [
1186+ {tag: "mako", deviceName: "mako"},
1187+ {tag: "manta", deviceName: "manta"},
1188+ {tag: "flo", deviceName: "flo"}
1189+ ];
1190+ }
1191+ function test_portraitOnlyAppInLandscapeDesktop(data) {
1192+ loadShell(data.deviceName);
1193+
1194+ ////
1195+ // setup preconditions (put shell in Desktop mode and landscape)
1196+
1197+ usageModeSelector.selectWindowed();
1198+
1199+ orientedShell.physicalOrientation = orientedShell.orientations.landscape;
1200+ waitUntilShellIsInOrientation(orientedShell.orientations.landscape);
1201+ waitForRotationAnimationsToFinish();
1202+
1203+ ////
1204+ // Launch a portrait-only application
1205+
1206+ var dialerApp = ApplicationManager.startApplication("dialer-app");
1207+ verify(dialerApp);
1208+
1209+ // ensure the mock dialer-app is as we expect
1210+ compare(dialerApp.rotatesWindowContents, false);
1211+ compare(dialerApp.supportedOrientations, Qt.PortraitOrientation | Qt.InvertedPortraitOrientation);
1212+
1213+ waitUntilAppSurfaceShowsUp("dialer-app");
1214+ waitUntilAppWindowCanRotate("dialer-app");
1215+ verify(isAppSurfaceFocused("dialer-app"));
1216+
1217+ ////
1218+ // check outcome (shell should stay in landscape)
1219+
1220+ waitForRotationAnimationsToFinish();
1221+ compare(shell.orientation, orientedShell.orientations.landscape);
1222+ }
1223+
11431224 // angle - rotation angle in degrees clockwise, relative to the primary orientation.
11441225 function rotateTo(angle) {
11451226 switch (angle) {
@@ -1158,7 +1239,10 @@ Rectangle {
11581239 default:
11591240 verify(false);
11601241 }
1242+ waitForRotationAnimationsToFinish();
1243+ }
11611244
1245+ function waitForRotationAnimationsToFinish() {
11621246 var rotationStates = findInvisibleChild(orientedShell, "rotationStates");
11631247 verify(rotationStates.d);
11641248 verify(rotationStates.d.stateUpdateTimer);
tests/qmltests/tst_Shell.qml+75−6
@@ -18,7 +18,7 @@ import QtQuick 2.4
1818import QtTest 1.0
1919import AccountsService 0.1
2020import GSettings 1.0
21−import LightDM.IntegratedLightDM 0.1 as LightDM
21+import IntegratedLightDM 0.1 as LightDM
2222import Ubuntu.Components 1.3
2323import Ubuntu.Components.ListItems 1.3 as ListItem
2424import Ubuntu.Telephony 0.1 as Telephony
@@ -49,6 +49,11 @@ Rectangle {
4949 shellLoader.active = true;
5050 }
5151
52+ MouseArea {
53+ id: clickThroughCatcher
54+ anchors.fill: shellContainer
55+ }
56+
5257 Item {
5358 id: shellContainer
5459 anchors.left: root.left
@@ -291,11 +296,31 @@ Rectangle {
291296 signalName: "applicationRemoved"
292297 }
293298
299+ SignalSpy {
300+ id: clickThroughSpy
301+ target: clickThroughCatcher
302+ signalName: "clicked"
303+ }
304+
294305 Telephony.CallEntry {
295306 id: phoneCall
296307 phoneNumber: "+447812221111"
297308 }
298309
310+ Item {
311+ id: fakeDismissTimer
312+ property bool running: false
313+ signal triggered
314+
315+ function stop() {
316+ running = false;
317+ }
318+
319+ function restart() {
320+ running = true;
321+ }
322+ }
323+
299324 UnityTestCase {
300325 id: testCase
301326 name: "Shell"
@@ -333,6 +358,11 @@ Rectangle {
333358 var launcher = findChild(shell, "launcher");
334359 launcherShowDashHomeSpy.target = launcher;
335360
361+ var panel = findChild(launcher, "launcherPanel");
362+ verify(!!panel);
363+
364+ panel.dismissTimer = fakeDismissTimer;
365+
336366 waitForGreeterToStabilize();
337367 }
338368
@@ -631,7 +661,6 @@ Rectangle {
631661 // again before interacting with it otherwise any
632662 // DirectionalDragAreas in there won't be easily fooled by
633663 // fake swipes.
634− removeTimeConstraintsFromDirectionalDragAreas(greeter);
635664 swipeAwayGreeter();
636665
637666 compare(mainApp.requestedState, ApplicationInfoInterface.RequestedRunning);
@@ -641,6 +670,7 @@ Rectangle {
641670 function swipeAwayGreeter() {
642671 var greeter = findChild(shell, "greeter");
643672 tryCompare(greeter, "fullyShown", true);
673+ removeTimeConstraintsFromDirectionalDragAreas(greeter);
644674
645675 var touchX = shell.width - (shell.edgeSize / 2);
646676 var touchY = shell.height / 2;
@@ -1240,10 +1270,6 @@ Rectangle {
12401270
12411271 var launcher = findChild(shell, "launcher");
12421272
1243− // ensure the launcher dimissal timer never gets triggered during the test run
1244− var dismissTimer = findInvisibleChild(launcher, "dismissTimer");
1245− dismissTimer.interval = 60 * 60 * 1000;
1246−
12471273 dragLauncherIntoView();
12481274
12491275 // Emulate a tap with a finger, where the touch position drifts during the tap.
@@ -1731,6 +1757,7 @@ Rectangle {
17311757
17321758 revealLauncherByEdgePushWithMouse();
17331759 tryCompare(launcher, "x", 0);
1760+ mouseMove(bfb, bfb.width / 2, bfb.height / 2)
17341761 waitForRendering(shell)
17351762
17361763 mouseClick(bfb, bfb.width / 2, bfb.height / 2)
@@ -1961,5 +1988,47 @@ Rectangle {
19611988 compare(ApplicationManager.findApplication("libreoffice") === null, true);
19621989 }
19631990 }
1991+
1992+ function test_inputEventsOnEdgesEndUpInAppSurface_data() {
1993+ return [
1994+ { tag: "phone", repeaterName: "spreadRepeater" },
1995+ { tag: "tablet", repeaterName: "spreadRepeater" },
1996+ { tag: "desktop", repeaterName: "appRepeater" },
1997+ ]
1998+ }
1999+
2000+ function test_inputEventsOnEdgesEndUpInAppSurface(data) {
2001+ loadShell(data.tag);
2002+ shell.usageScenario = data.tag;
2003+ waitForRendering(shell);
2004+ swipeAwayGreeter();
2005+
2006+ // Let's open a fullscreen app
2007+ var app = ApplicationManager.startApplication("camera-app");
2008+ waitUntilAppWindowIsFullyLoaded(app);
2009+
2010+ var appRepeater = findChild(shell, data.repeaterName);
2011+ var topmostAppDelegate = appRepeater.itemAt(0);
2012+ verify(topmostAppDelegate);
2013+
2014+ var topmostSurfaceItem = findChild(topmostAppDelegate, "surfaceItem");
2015+ verify(topmostSurfaceItem);
2016+
2017+ mouseClick(shell, 1, shell.height / 2);
2018+ compare(topmostSurfaceItem.mousePressCount, 1);
2019+ compare(topmostSurfaceItem.mouseReleaseCount, 1);
2020+
2021+ mouseClick(shell, shell.width - 1, shell.height / 2);
2022+ compare(topmostSurfaceItem.mousePressCount, 2);
2023+ compare(topmostSurfaceItem.mouseReleaseCount, 2);
2024+
2025+ tap(shell, 1, shell.height / 2);
2026+ compare(topmostSurfaceItem.touchPressCount, 1);
2027+ compare(topmostSurfaceItem.touchReleaseCount, 1);
2028+
2029+ tap(shell, shell.width - 1, shell.height / 2);
2030+ compare(topmostSurfaceItem.touchPressCount, 2);
2031+ compare(topmostSurfaceItem.touchReleaseCount, 2);
2032+ }
19642033 }
19652034}
tests/qmltests/tst_ShellWithPin.qml+19−5
@@ -128,6 +128,20 @@ Item {
128128 phoneNumber: "+447812221111"
129129 }
130130
131+ Item {
132+ id: fakeDismissTimer
133+ property bool running: false
134+ signal triggered
135+
136+ function stop() {
137+ running = false;
138+ }
139+
140+ function restart() {
141+ running = true;
142+ }
143+ }
144+
131145 UT.UnityTestCase {
132146 id: testCase
133147 name: "ShellWithPin"
@@ -143,6 +157,11 @@ Item {
143157 waitForLockscreen()
144158 greeter.failedLoginsDelayAttempts = -1;
145159 greeter.maxFailedLogins = -1;
160+
161+ var launcher = findChild(shell, "launcher");
162+ var panel = findChild(launcher, "launcherPanel");
163+ verify(!!panel);
164+ panel.dismissTimer = fakeDismissTimer;
146165 }
147166
148167 function cleanup() {
@@ -565,11 +584,6 @@ Item {
565584 tryCompare(coverPage, "showProgress", 1);
566585
567586 var launcher = testCase.findChild(shell, "launcher")
568− {
569− var dismissTimer = testCase.findInvisibleChild(launcher, "dismissTimer");
570− // effectively disable the dismiss timer
571− dismissTimer.interval = 24 * 60 * 60 * 1000 // 24 hours
572− }
573587 var launcherPanel = testCase.findChild(launcher, "launcherPanel");
574588
575589 var toX = shell.width * 0.45;
tests/utils/modules/Unity/Test/CMakeLists.txt+8−1
@@ -13,12 +13,19 @@ set(UnityTestQML_SOURCES
1313 testutil.cpp
1414 plugin.cpp
1515 TouchEventSequenceWrapper.cpp
16− ${CMAKE_SOURCE_DIR}/src/MouseTouchAdaptor.cpp
1716)
1817
18+if (ENABLE_TOUCH_EMULATION)
19+ set(UnityTestQML_SOURCES ${UnityTestQML_SOURCES} ${CMAKE_SOURCE_DIR}/src/MouseTouchAdaptor.cpp)
20+endif()
21+
1922add_library(UnityTestQml MODULE ${UnityTestQML_SOURCES})
2023target_link_libraries(UnityTestQml UbuntuGestures)
2124
25+if (ENABLE_TOUCH_EMULATION)
26+ target_link_libraries(UnityTestQml ${MOUSETOUCHADAPTOR_LIBS_LDFLAGS})
27+endif()
28+
2229qt5_use_modules(UnityTestQml Core Quick Test)
2330
2431export_qmlfiles(Unity.Test Unity/Test)
tests/utils/modules/Unity/Test/plugin.cpp+13−3
@@ -17,7 +17,11 @@
1717
1818#include "plugin.h"
1919#include "testutil.h"
20+
21+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
2022#include <MouseTouchAdaptor.h>
23+#endif
24+
2125#include "TouchEventSequenceWrapper.h"
2226
2327#include <qqml.h>
@@ -27,23 +31,29 @@ QObject *testutil_provider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine
2731{
2832 return new TestUtil();
2933}
34+
35+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
3036QObject *getMouseTouchAdaptorQMLSingleton(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
3137{
3238 return MouseTouchAdaptor::instance();
3339}
40+#endif
41+
3442} // anonymous namespace
3543
3644void UnityTestPlugin::registerTypes(const char *uri)
3745{
3846 Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Test"));
3947
40− // Ensure the instance gets created
41− MouseTouchAdaptor::instance();
42−
4348 // @uri Unity.Test
4449 qmlRegisterSingletonType<TestUtil>(uri, 0, 1, "Util", testutil_provider);
4550 qmlRegisterUncreatableType<TouchEventSequenceWrapper>(uri, 0, 1, "TouchEventSequence",
4651 "You cannot directly create a TouchEventSequence object.");
52+
53+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
54+ // Ensure the instance gets created
55+ MouseTouchAdaptor::instance();
4756 qmlRegisterSingletonType<MouseTouchAdaptor>(uri, 0, 1, "MouseTouchAdaptor",
4857 getMouseTouchAdaptorQMLSingleton);
58+ #endif
4959}