Merge lp:~mterry/unity8/tutorial-redesign into lp:unity8

Proposed by Michael Terry
Status: Superseded
Proposed branch: lp:~mterry/unity8/tutorial-redesign
Merge into: lp:unity8
Prerequisite: lp:~mzanetti/unity8/catch-osk
Diff against target: 19733 lines (+9629/-3653)
233 files modified
CMakeLists.txt (+2/-1)
cmake/modules/QmlTest.cmake (+1/-1)
data/com.canonical.Unity8.gschema.xml (+11/-0)
data/unity8-dash.conf (+1/-0)
debian/changelog (+97/-0)
debian/control (+9/-7)
debian/unity8-common.udev (+2/-0)
debian/unity8-doc.install (+1/-0)
doc/devices.conf (+30/-0)
plugins/AccountsService/AccountsService.cpp (+286/-399)
plugins/AccountsService/AccountsService.h (+42/-24)
plugins/AccountsService/AccountsService.qmltypes (+5/-0)
plugins/AccountsService/AccountsServiceDBusAdaptor.cpp (+11/-4)
plugins/AccountsService/AccountsServiceDBusAdaptor.h (+5/-6)
plugins/AccountsService/com.canonical.unity.AccountsService.xml (+5/-0)
plugins/Dash/AudioProgressBar.qml (+1/-0)
plugins/Dash/CardCreator.js (+69/-34)
plugins/Dash/CardCreatorCache.qml (+3/-3)
plugins/Dash/plugin.cpp (+6/-6)
plugins/GlobalShortcut/globalshortcutregistry.cpp (+4/-4)
plugins/IntegratedLightDM/liblightdm/CMakeLists.txt (+16/-3)
plugins/IntegratedLightDM/liblightdm/UsersModel.cpp (+4/-18)
plugins/IntegratedLightDM/liblightdm/UsersModel.h (+1/-1)
plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp (+44/-10)
plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h (+15/-3)
plugins/ScreenGrabber/screengrabber.cpp (+0/-2)
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp (+40/-5)
plugins/Ubuntu/Gestures/DirectionalDragArea.h (+8/-0)
plugins/Ubuntu/Gestures/DirectionalDragArea_p.h (+2/-0)
plugins/Unity/Indicators/indicatorsmanager.cpp (+2/-2)
plugins/Unity/Indicators/rootstateparser.h (+1/-0)
plugins/Unity/Launcher/desktopfilehandler.cpp (+2/-2)
plugins/Unity/Launcher/launcheritem.cpp (+1/-0)
plugins/Unity/Launcher/launcheritem.h (+1/-1)
plugins/Unity/Launcher/launchermodel.cpp (+15/-5)
plugins/Unity/Launcher/launchermodel.h (+1/-1)
plugins/Utils/CMakeLists.txt (+2/-1)
plugins/Utils/Utils.qmltypes (+2/-2)
plugins/Utils/deviceconfigparser.cpp (+150/-0)
plugins/Utils/deviceconfigparser.h (+62/-0)
plugins/Utils/plugin.cpp (+4/-2)
plugins/Utils/timezoneFormatter.cpp (+10/-0)
plugins/Utils/timezoneFormatter.h (+1/-0)
plugins/Utils/windowinputfilter.cpp (+14/-16)
plugins/Utils/windowinputfilter.h (+11/-11)
plugins/Wizard/CMakeLists.txt (+7/-1)
plugins/Wizard/LocalePlugin.cpp (+291/-0)
plugins/Wizard/LocalePlugin.h (+58/-0)
plugins/Wizard/PageList.cpp (+4/-4)
plugins/Wizard/Status.cpp (+143/-0)
plugins/Wizard/Status.h (+60/-0)
plugins/Wizard/System.cpp (+5/-4)
plugins/Wizard/System.h (+3/-2)
plugins/Wizard/plugin.cpp (+7/-8)
plugins/Wizard/plugin.h (+1/-2)
plugins/Wizard/timezonemodel.cpp (+239/-0)
plugins/Wizard/timezonemodel.h (+80/-0)
po/unity8.pot (+29/-27)
qml/Components/EdgeBarrier.qml (+1/-1)
qml/Components/Lockscreen.qml (+86/-100)
qml/Components/ModeSwitchWarningDialog.qml (+1/-1)
qml/Components/PassphraseLockscreen.qml (+5/-4)
qml/Components/PhysicalKeysMapper.qml (+24/-0)
qml/Components/PinLockscreen.qml (+22/-1)
qml/Components/ShellDialog.qml (+8/-0)
qml/Dash/CardCarousel.qml (+0/-1)
qml/Dash/CardGrid.qml (+0/-1)
qml/Dash/CardHorizontalList.qml (+0/-1)
qml/Dash/CardTool.qml (+2/-26)
qml/Dash/CardVerticalJournal.qml (+0/-1)
qml/Dash/Dash.qml (+11/-11)
qml/Dash/GenericScopeView.qml (+2/-0)
qml/Dash/Previews/PreviewHeader.qml (+37/-9)
qml/Dash/Previews/PreviewOverlay.qml (+1/-1)
qml/Dash/Previews/PreviewSharing.qml (+17/-7)
qml/Dash/ScopesListCategoryItem.qml (+8/-4)
qml/DeviceConfiguration.qml (+56/-18)
qml/DisabledScreenNotice.qml (+44/-20)
qml/Greeter/CoverPage.qml (+13/-2)
qml/Greeter/Greeter.qml (+10/-6)
qml/Greeter/Infographics.qml (+2/-1)
qml/Greeter/NarrowView.qml (+14/-1)
qml/Launcher/Launcher.qml (+144/-12)
qml/Launcher/LauncherDelegate.qml (+55/-20)
qml/Launcher/LauncherPanel.qml (+122/-51)
qml/Launcher/graphics/launcher-app-focus-ring.svg (+12/-0)
qml/Notifications/Notification.qml (+6/-2)
qml/OrientedShell.qml (+26/-1)
qml/Panel/Handle.qml (+2/-2)
qml/Panel/Indicators/MenuItemFactory.qml (+0/-1)
qml/Panel/IndicatorsMenu.qml (+1/-3)
qml/Panel/Panel.qml (+5/-1)
qml/ScopeTool.qml (+0/-8)
qml/Shell.qml (+77/-46)
qml/Stages/AbstractStage.qml (+4/-1)
qml/Stages/ApplicationWindow.qml (+0/-2)
qml/Stages/DesktopSpread.qml (+64/-17)
qml/Stages/DesktopSpreadDelegate.qml (+15/-1)
qml/Stages/DesktopStage.qml (+34/-34)
qml/Stages/PhoneStage.qml (+80/-9)
qml/Stages/SpreadDelegate.qml (+20/-0)
qml/Stages/TabletStage.qml (+98/-14)
qml/Stages/WindowResizeArea.qml (+8/-5)
qml/Tutorial/Arrow.qml (+0/-56)
qml/Tutorial/InactivityTimer.qml (+62/-0)
qml/Tutorial/Slider.qml (+0/-123)
qml/Tutorial/Tick.qml (+0/-29)
qml/Tutorial/Tutorial.qml (+43/-18)
qml/Tutorial/TutorialBottom.qml (+0/-104)
qml/Tutorial/TutorialBottomFinish.qml (+0/-41)
qml/Tutorial/TutorialContent.qml (+250/-80)
qml/Tutorial/TutorialLeft.qml (+28/-75)
qml/Tutorial/TutorialLeftFinish.qml (+0/-41)
qml/Tutorial/TutorialLeftLong.qml (+54/-0)
qml/Tutorial/TutorialPage.qml (+66/-190)
qml/Tutorial/TutorialRight.qml (+0/-223)
qml/Tutorial/TutorialTop.qml (+61/-0)
qml/Tutorial/graphics/arrow.svg (+19/-0)
qml/Wizard/CheckableSetting.qml (+10/-2)
qml/Wizard/Page.qml (+274/-58)
qml/Wizard/Pages.qml (+76/-32)
qml/Wizard/Pages/10-welcome.qml (+129/-56)
qml/Wizard/Pages/30-wifi.qml (+119/-128)
qml/Wizard/Pages/40-location.qml (+216/-75)
qml/Wizard/Pages/50-timezone.qml (+275/-0)
qml/Wizard/Pages/60-account.qml (+74/-0)
qml/Wizard/Pages/60-reporting.qml (+0/-64)
qml/Wizard/Pages/70-passwd-type.qml (+105/-79)
qml/Wizard/Pages/75-report-check.qml (+91/-0)
qml/Wizard/Pages/80-finished.qml (+106/-28)
qml/Wizard/Pages/here-terms.qml (+80/-73)
qml/Wizard/Pages/passcode-confirm.qml (+13/-30)
qml/Wizard/Pages/passcode-desktop.qml (+132/-0)
qml/Wizard/Pages/passcode-set.qml (+12/-28)
qml/Wizard/Pages/password-set.qml (+149/-0)
qml/Wizard/Pages/sim.qml (+71/-40)
qml/Wizard/PasswordMeter.qml (+106/-0)
qml/Wizard/StackButton.qml (+6/-11)
qml/Wizard/Wizard.qml (+0/-9)
qml/Wizard/WizardTextField.qml (+25/-0)
src/CMakeLists.txt (+1/-1)
src/CachingNetworkManagerFactory.cpp (+2/-2)
src/CachingNetworkManagerFactory.h (+3/-2)
src/Dash/CMakeLists.txt (+1/-1)
tests/autopilot/unity8/dash.py (+1/-2)
tests/autopilot/unity8/shell/emulators.py (+0/-2)
tests/autopilot/unity8/shell/tests/test_helpers.py (+0/-2)
tests/autopilot/unity8/shell/tests/test_tutorial.py (+0/-57)
tests/autopilot/unity8/tutorial.py (+0/-73)
tests/mocks/AccountsService/AccountsService.cpp (+43/-3)
tests/mocks/AccountsService/AccountsService.h (+22/-5)
tests/mocks/AccountsService/AccountsService.qmltypes (+5/-0)
tests/mocks/GSettings.1.0/fake_gsettings.cpp (+64/-0)
tests/mocks/GSettings.1.0/fake_gsettings.h (+18/-0)
tests/mocks/IntegratedLightDM/liblightdm/UsersModel.cpp (+0/-14)
tests/mocks/MeeGo/QOfono/MockOfonoSimManager.qml (+1/-0)
tests/mocks/Ubuntu/Connectivity/plugin.cpp (+1/-0)
tests/mocks/Ubuntu/SystemSettings/CMakeLists.txt (+2/-0)
tests/mocks/Ubuntu/SystemSettings/Diagnostics/CMakeLists.txt (+1/-0)
tests/mocks/Ubuntu/SystemSettings/Diagnostics/MockDiagnostics.qml (+24/-0)
tests/mocks/Ubuntu/SystemSettings/Diagnostics/qmldir (+2/-0)
tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockLanguagePlugin.qml (+2/-2)
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.cpp (+1/-1)
tests/mocks/Ubuntu/SystemSettings/TimeDate/CMakeLists.txt (+1/-0)
tests/mocks/Ubuntu/SystemSettings/TimeDate/MockTimeDate.qml (+25/-0)
tests/mocks/Ubuntu/SystemSettings/TimeDate/qmldir (+2/-0)
tests/mocks/Unity/Application/ApplicationInfo.h (+1/-1)
tests/mocks/Unity/Application/MirSurface.cpp (+3/-0)
tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+2/-0)
tests/mocks/Utils/CMakeLists.txt (+3/-2)
tests/mocks/Utils/Utils.qmltypes (+2/-2)
tests/mocks/Utils/plugin.cpp (+7/-2)
tests/mocks/Wizard/CMakeLists.txt (+6/-1)
tests/mocks/Wizard/MockSystem.cpp (+4/-2)
tests/mocks/Wizard/MockSystem.h (+2/-2)
tests/mocks/Wizard/mockplugin.cpp (+7/-8)
tests/plugins/AccountsService/CMakeLists.txt (+5/-0)
tests/plugins/AccountsService/PropertiesServer.cpp (+17/-4)
tests/plugins/AccountsService/PropertiesServer.h (+2/-1)
tests/plugins/AccountsService/UscServer.cpp (+28/-0)
tests/plugins/AccountsService/UscServer.h (+39/-0)
tests/plugins/AccountsService/client.cpp (+100/-9)
tests/plugins/AccountsService/interfaces.xml (+16/-0)
tests/plugins/AccountsService/server.cpp (+12/-0)
tests/plugins/Dash/cardcreator/1.res (+4/-6)
tests/plugins/Dash/cardcreator/1.res.cardcreator (+119/-0)
tests/plugins/Dash/cardcreator/10.res (+3/-5)
tests/plugins/Dash/cardcreator/10.res.cardcreator (+137/-0)
tests/plugins/Dash/cardcreator/11.res (+5/-7)
tests/plugins/Dash/cardcreator/11.res.cardcreator (+210/-0)
tests/plugins/Dash/cardcreator/2.res (+3/-5)
tests/plugins/Dash/cardcreator/2.res.cardcreator (+136/-0)
tests/plugins/Dash/cardcreator/3.res (+3/-5)
tests/plugins/Dash/cardcreator/3.res.cardcreator (+137/-0)
tests/plugins/Dash/cardcreator/4.res (+3/-5)
tests/plugins/Dash/cardcreator/4.res.cardcreator (+109/-0)
tests/plugins/Dash/cardcreator/5.res (+5/-7)
tests/plugins/Dash/cardcreator/5.res.cardcreator (+156/-0)
tests/plugins/Dash/cardcreator/6.res (+2/-4)
tests/plugins/Dash/cardcreator/6.res.cardcreator (+126/-0)
tests/plugins/Dash/cardcreator/7.res (+3/-5)
tests/plugins/Dash/cardcreator/7.res.cardcreator (+149/-0)
tests/plugins/Dash/cardcreator/8.res (+3/-5)
tests/plugins/Dash/cardcreator/8.res.cardcreator (+107/-0)
tests/plugins/Dash/cardcreator/9.res (+4/-5)
tests/plugins/Dash/cardcreator/9.res.cardcreator (+119/-0)
tests/plugins/Dash/cardcreatortest.cpp (+35/-25)
tests/plugins/Dash/cardcreatortest.qml (+4/-4)
tests/plugins/IntegratedLightDM/CMakeLists.txt (+25/-0)
tests/plugins/IntegratedLightDM/integrated.cpp (+91/-0)
tests/plugins/Utils/CMakeLists.txt (+7/-1)
tests/plugins/Utils/DeviceConfigParserTest.cpp (+70/-0)
tests/qmltests/CMakeLists.txt (+1/-0)
tests/qmltests/Components/tst_Lockscreen.qml (+14/-7)
tests/qmltests/Components/tst_PhysicalKeysMapper.qml (+3/-3)
tests/qmltests/Dash/Previews/tst_PreviewHeader.qml (+18/-1)
tests/qmltests/Dash/Previews/tst_PreviewSharing.qml (+17/-3)
tests/qmltests/Dash/tst_CardTool.qml (+4/-4)
tests/qmltests/Dash/tst_Dash.qml (+89/-0)
tests/qmltests/Greeter/tst_Greeter.qml (+7/-1)
tests/qmltests/Greeter/tst_NarrowView.qml (+9/-0)
tests/qmltests/Launcher/tst_Launcher.qml (+254/-18)
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml (+2/-4)
tests/qmltests/Stages/tst_DesktopStage.qml (+2/-1)
tests/qmltests/Stages/tst_PhoneStage.qml (+19/-6)
tests/qmltests/Stages/tst_SpreadDelegate.qml (+7/-0)
tests/qmltests/Stages/tst_TabletStage.qml (+19/-1)
tests/qmltests/Tutorial/tst_Tutorial.qml (+639/-245)
tests/qmltests/Wizard/tst_Wizard.qml (+186/-215)
tests/qmltests/tst_DeviceConfiguration.qml (+49/-0)
tests/qmltests/tst_DisabledScreenNotice.qml (+76/-2)
tests/qmltests/tst_Shell.qml (+245/-68)
tests/qmltests/tst_ShellWithPin.qml (+0/-22)
To merge this branch: bzr merge lp:~mterry/unity8/tutorial-redesign
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Needs Fixing
PS Jenkins bot continuous-integration Pending
Albert Astals Cid merges fine Pending
Michael Zanetti Pending
Review via email: mp+288674@code.launchpad.net

This proposal supersedes a proposal from 2015-09-16.

This proposal has been superseded by a proposal from 2016-03-11.

Commit message

Redesign the first-boot edge tutorial

Description of the change

Based on new design specs [1], this is whole new tutorial code.

Some of the interesting things going on here:

- New DDA feature "monitorOnly" which lets input events "fall through" (i.e. it doesn't own them) but continues to monitor them. This is how we implement the bottom edge tutorial fading out without having to communicate with the app.

- New AccountsService key to keep track of which particular edges are done, now that they are presented separately. We still use the old key for overall "done" status.

- Renamed WindowKeysFilter to WindowInputFilter. I needed a way to keep track of input inactivity. And since WindowKeysFilter was already injecting itself into the event stream and already kept track of timestamps for us (which usually isn't exposed to Qml), I just modified it a bit. I felt like the new scope should be indicated in the name, so I renamed it.

- I took out some old hacks only needed for the old tutorial.

[1] https://docs.google.com/document/d/1pZ-Ro--2eaRzjZKNRoYAeDvQHMkCuyvVuPFWFQfPW4s/edit

== Checklist ==

 * Are there any related MPs required for this MP to build/function as expected? Please list.

 Yes. A new phablet-tools branch for your desktop [2] and a new upload of dbus-property-service (not in a VCS). Both are in silo 33.

 [2] https://code.launchpad.net/~mterry/phablet-tools/tutorial-redesign/+merge/277764

 * Did you perform an exploratory manual test run of your code change and any related functionality?
 Yes

 * Did you make sure that your branch does not contain spurious tags?
 Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
 NA

 * If you changed the UI, has there been a design review?
 Yes. Patricia is on board with this MP. She has another screen coming (long swipe on left), but I'll do that as a separate MP.

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

<dandrader> mterry, DDA changes in lp:~mterry/unity8/tutorial-redesign look fine
<mterry> dandrader, awesome, thanks
 will quote you in the MP :)
<dandrader> mterry, only unsure about the property name. Because it will work all the same, only difference is that it won't claim ownership over the touch point once it recognizes it's performing a gesture
<mterry> dandrader, yeah. I'm happy to rename it. Got something you like better?
<dandrader> mterry, no :)

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

OK, I'm opening this up to review, although the final design review isn't done yet and I need to add a couple more qmltests. But I'd like to get the review train started on its way.

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

OK, added more tests and cleaned up existing ones. Hopefully this is "done-ish" from a technical POV and only design-related changes will happen now (like changes to strings or alignment).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1977
http://jenkins.qa.ubuntu.com/job/unity8-ci/6737/
Executed test runs:
    ABORTED: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5244/console
    ABORTED: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/152/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1450
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/152
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1344
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1345
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/151
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/151
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4164/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5264
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5264/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/33/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/152
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/152/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6737/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1978
http://jenkins.qa.ubuntu.com/job/unity8-ci/6739/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5250
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/154/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1452
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/154/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1346
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1347
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/153
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/153
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4168
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5270
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5270/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25246
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/34/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/154
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/154/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25244

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6739/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Hmm... I've just flashed a device and enabled the edges-intro with phablet-config. I could see the intro for left, top and bottom edges, however, still waiting for the right edge one to appear.

====

As you renamed WindowKeyFilter, please update this comment too

qml/Shell.qml: // dummy shortcut to force creation of GlobalShortcutRegistry before WindowKeyFilter

===

- readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
+ dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0

Given that it's not obvious what the dragProgress is used for, please add a comment in the stages code to indicate it. otherwise it's likely to be removed at some point because noone knows what it does.

===

+ ////

Is there a purpose to this? :)

===
+ sourceSize.height: 1080
+ sourceSize.width: 1916

erm... can you explain the values? Looks wrong to me

review: Needs Fixing
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Notes for myself:

* test if CPU usage drops if screen locks during animation
* test what happens if plugging external screen while in tutorial

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal
Download full text (3.2 KiB)

OK, I've made some changes. One, I added some more space between tutorial text lines, per design request.

Second, also per design request, I've added unique helper text on the bottom edge tutorial for each supported app. This also means that we show the tutorial for each app rather than once for any of them. Since this meant that the tutorial might not formally "finish" for quite some time, I've optimized the rest of the tutorial to use Loaders. So that we're not loading three unused background images a week after the user unboxes their phone.

As for your comments:

> Hmm... I've just flashed a device and enabled the edges-intro
> with phablet-config. I could see the intro for left, top and
> bottom edges, however, still waiting for the right edge one to appear.

As discussed on IRC, we're guessing this was user error. Unless you've seen it again?

====

> As you renamed WindowKeyFilter, please update this comment too
>
> qml/Shell.qml: // dummy shortcut to force creation of GlobalShortcutRegistry before WindowKeyFilter

Done.

===

> - readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
> + dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0

> Given that it's not obvious what the dragProgress is used for,
> please add a comment in the stages code to indicate it. otherwise
> it's likely to be removed at some point because noone knows what it does.

Done.

===

> + ////
>
> Is there a purpose to this? :)

Ah, that's just a little visual separator I use between the public interface part of the object and the implementation parts. Qml doesn't use headers, and while we seem to use the placement of the QtObject component to separate the portions of code, sometimes an object doesn't warrant a QtObject, so it isn't a universal distinguisher. Plus, I like the extra visual space.

I can take it out if it will be as confusing to you as others. I know Cimi doesn't like that I do that.

===

> + sourceSize.height: 1080
> + sourceSize.width: 1916
>
> erm... can you explain the values? Looks wrong to me

Duh, I swapped height and width. Fixed.

===

> * test if CPU usage drops if screen locks during animation

Please do, but note that there isn't any animation anymore. So I expect no CPU difference.

===

> * test what happens if plugging external screen while in tutorial

Ah yes. Here's what I expect the code to do:

- Any visible tutorials that aren't marked for desktop use will fade out.
- The right edge tutorial will appear (or update itself) with desktop-specific text when you have enough apps open.
- If you finish the right edge tutorial while in desktop mode, the tutorial will be marked complete and you won't see any more coach marks. However, if you don't finish the right edge tutorial before undocking, you will continue to see all the tutorials you haven't seen yet, as normal.

How do you feel about that last behavior? It might be tricky to do something much smarter unless either (A) we know the "native" usageScenario of the device or (B) we stop marking the "whole-tutorial-is-complete" flag and accept that if we add new pages or redesign th...

Read more...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1979
http://jenkins.qa.ubuntu.com/job/unity8-ci/6745/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5277
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/160/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1458
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/160/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1352
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1353
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/159
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/159
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4186
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5297
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5297/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25290
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/37/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/160
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/160/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25292

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6745/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1981
http://jenkins.qa.ubuntu.com/job/unity8-ci/6749/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5285
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/164/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1462
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/164/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1356
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1357
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/163
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/163
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4194
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5305
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5305/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25309
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/40/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/164
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/164/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25308

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6749/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in tests/plugins/AccountsService/PropertiesServer.cpp
1 conflicts encountered.

review: Needs Fixing
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

Fixed conflicts.

Revision history for this message
Albert Astals Cid (aacid) : Posted in a previous version of this proposal
review: Abstain (merges fine)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1983
http://jenkins.qa.ubuntu.com/job/unity8-ci/6787/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5345
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/202/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1500
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/202/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1394
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1395
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/201
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/201
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4239
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5365
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5365/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25431
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/63/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/202
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/202/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25433

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6787/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1984
http://jenkins.qa.ubuntu.com/job/unity8-ci/6794/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5367
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/209/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1507
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/209/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1401
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1402
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/208
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/208
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4256
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5387
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5387/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25462
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/67/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/209
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/209/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25460

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6794/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1985
http://jenkins.qa.ubuntu.com/job/unity8-ci/6823/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5458
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/238/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1534
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/236
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1429
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1429
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/236
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/235
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4306
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5472
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5472/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25583
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/82/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/237
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/237/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25582

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6823/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1986
http://jenkins.qa.ubuntu.com/job/unity8-ci/6834/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5490
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/249/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1545
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/248
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1440
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1440
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/247
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/246
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4318
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5504
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5504/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25632
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/88/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/248
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/248/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25631

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6834/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

+ i18n.tr("Hover your mouse on the right edge to view your open apps") :
+ i18n.tr("Short or long swipe from the right edge to view your open apps")

I know those have been given by design, but gotta point out some errors:
- In windowed mode, you need to push the mouse against the right edge and even overcome some resistance. Hovering is not enough.
- While at it, we might want to ask back on short swipe one too, but I guess that would be ok to oversimplify it in this case.

========

+ text: d.landscape ? i18n.tr("Swipe from the top right edge to open the notification bar")
+ : i18n.tr("Swipe from the top edge to open the notification bar")

this might needs a windowed mode special case too. We don't want to encourage clicking with a mouse so the indicators can also be revealed by clicking the icons. Although this is not wrong. If you have a touch screen too, you can also swipe then on a desktop.

========

+ text: i18n.tr("Swipe from the left edge to open the launcher")

same as for the right edge. With a mouse, it requires pushing towards the edge. Why not special cased here?

review: Needs Information
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Another question:

I figure it will take ages until completed goes to true. Some people might never open the calculator app which would leave us with the tutorial being enabled forever. What are the implications of that?

review: Needs Information
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

You mention the wording on the left edge drag needing to be changed for desktop mode -- but we don't show that tutorial on desktop. So I'm guessing we can leave it as is.

And you asked about the tutorial never "completing". This is a small issue. And it's why I revised TutorialContent to use loaders for each tutorial page. I don't think it's a problem, per se. But it does mean that we'll likely have the TutorialBottom page loaded most of the time. Until they load all the bottom-supported apps anyway...

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

On the right edge in windowed mode, it's not only the text, but the hoverMouseArea disappered and it's not possible to get past that step any more.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1987
http://jenkins.qa.ubuntu.com/job/unity8-ci/6940/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5756
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/355/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1651
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/354
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1546
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1546
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/353
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/352
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4467
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5769
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5769/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26035
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/130/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/354
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/354/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26036

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6940/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in qml/Launcher/Launcher.qml
1 conflicts encountered.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1987
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/35/
Executed test runs:

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/35/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1988
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/124/
Executed test runs:

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/124/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1988
http://jenkins.qa.ubuntu.com/job/unity8-ci/7092/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6059
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/507/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1797
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/500
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1692
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1692
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/499
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/498
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4680
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6070
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6070/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26746
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/247/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/505
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/505/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26745

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7092/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1989
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/168/
Executed test runs:

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/168/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1989
http://jenkins.qa.ubuntu.com/job/unity8-ci/7129/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6133
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/544/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1834
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/537
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1729
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1729
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/536
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/535
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4732
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6144
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6144/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26923
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/280/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/542
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/542/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26924

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7129/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1989
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/168/
Executed test runs:

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/168/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in qml/Stages/PhoneStage.qml
Text conflict in qml/Stages/TabletStage.qml
2 conflicts encountered.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1990
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/322/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/443/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/466
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/484
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/484
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/480
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/480/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/480/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/480
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/480/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/480/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/480
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/480/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/480/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/322/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1990
http://jenkins.qa.ubuntu.com/job/unity8-ci/7260/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6417
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/675/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1965
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/668
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1860
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1860
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/667
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/666
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4914
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6428
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6428/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27481
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/347/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/673
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/673/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27480

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7260/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1992
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/385/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/523
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay/165
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial/165
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/546
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/564
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/564
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/560/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/385/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1992
http://jenkins.qa.ubuntu.com/job/unity8-ci/7323/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6516
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/738/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/2028
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/731
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1923
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1923
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/730
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/729
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4975
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6527
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6527/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27663
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/383/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/736
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/736/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27664

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7323/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1993
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/390/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/528
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay/170
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial/170
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/551
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/569
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/569
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/565/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/390/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1993
http://jenkins.qa.ubuntu.com/job/unity8-ci/7328/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6521
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/743/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/2033
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/736
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1928
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1928
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/735
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/734
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4980
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6532
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6532/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27677
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/388/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/741
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/741/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27678

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7328/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1995
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/452/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/607
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay/191
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial/191
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/630
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/648
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/648
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/644/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/452/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1995
http://jenkins.qa.ubuntu.com/job/unity8-ci/7383/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6583
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/798/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/2088
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/791
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1983
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1983
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/790
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/789
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/5009
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6594
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6594/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27779
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/410/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/796
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/796/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27778

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7383/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1996
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/628/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/356
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/356
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/356
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/832
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/848
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/848
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/846/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/628/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

Tests need fixin ↑?

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

Fixed the qmluitest, and removed the autopilot test. The tutorial is harder to test via one autopilot test now that the pages have been split up and separately triggered. Plus, we cover them well in qmluitests. And there's nothing autopilot-centric to test there.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1999
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/642/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/364
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/364
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/364
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/847
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/863
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/863
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/861/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/642/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2000
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/656/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/373
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/373
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/373
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/862
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/878
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/878
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/876/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/656/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2002
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/662/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/377
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/377
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/377
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/869
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/885
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/885
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/883/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/662/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2002
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/663/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/378
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/378
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/378
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/870
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/886
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/886
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/884/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/663/rebuild

review: Needs Fixing (continuous-integration)
lp:~mterry/unity8/tutorial-redesign updated
2003. By Michael Terry

Merge silo 64

2004. By Michael Terry

Merge oobe

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

2004. By Michael Terry

Merge oobe

2003. By Michael Terry

Merge silo 64

2002. By Michael Terry

Merge in catch-osk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-02-12 00:12:30 +0000
3+++ CMakeLists.txt 2016-03-11 18:12:46 +0000
4@@ -58,6 +58,7 @@
5 find_package(Qt5Sql 5.4 REQUIRED)
6
7 pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=13)
8+pkg_check_modules(GEONAMES REQUIRED geonames)
9 pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
10 pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
11 pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
12@@ -131,7 +132,7 @@
13 set(STDOUT_LOGGER "-o" "-,txt")
14 endif()
15
16-execute_process(COMMAND arch OUTPUT_VARIABLE ARCH)
17+execute_process(COMMAND dpkg-architecture -qDEB_HOST_ARCH OUTPUT_VARIABLE ARCH)
18 if (NOT ARCH MATCHES "arm*")
19 set(ENABLE_TOUCH_EMULATION true)
20 add_definitions(-DUNITY8_ENABLE_TOUCH_EMULATION)
21
22=== modified file 'cmake/modules/QmlTest.cmake'
23--- cmake/modules/QmlTest.cmake 2015-05-21 20:24:47 +0000
24+++ cmake/modules/QmlTest.cmake 2016-03-11 18:12:46 +0000
25@@ -183,7 +183,7 @@
26 cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
27 mangle_arguments()
28
29- bake_arguments("${QMLTEST_ARG_PREFIX}" args -qmljsdebugger=port:3768)
30+ bake_arguments("${QMLTEST_ARG_PREFIX}" args -qmljsdebugger=port:3768,3800)
31
32 set(qmltry_command
33 $<TARGET_FILE:${TARGET}>
34
35=== modified file 'data/com.canonical.Unity8.gschema.xml'
36--- data/com.canonical.Unity8.gschema.xml 2015-11-24 17:44:18 +0000
37+++ data/com.canonical.Unity8.gschema.xml 2016-03-11 18:12:46 +0000
38@@ -27,6 +27,17 @@
39 <summary>Maximum push needed to overcome edge barrier</summary>
40 <description>How much you have to push (in grid units) the mouse against an edge barrier when sensibility is 1.</description>
41 </key>
42+ <key type="b" name="autohide-launcher">
43+ <default>true</default>
44+ <summary>Autohide the launcher</summary>
45+ <description>This will only be applied in windowed mode. In staged mode, the launcher will always hide.</description>
46+ </key>
47+ <key type="u" name="launcher-width">
48+ <default>8</default>
49+ <range min="6" max="12"/>
50+ <summary>Width of the launcher in grid units.</summary>
51+ <description>Changes the width of the launcher in all usage modes.</description>
52+ </key>
53 </schema>
54
55 <schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8">
56
57=== modified file 'data/unity8-dash.conf'
58--- data/unity8-dash.conf 2015-04-21 15:41:09 +0000
59+++ data/unity8-dash.conf 2016-03-11 18:12:46 +0000
60@@ -14,6 +14,7 @@
61 oom score 50
62
63 respawn
64+respawn limit unlimited
65
66 env APP_ID=unity8-dash
67
68
69=== modified file 'debian/changelog'
70--- debian/changelog 2016-03-08 20:59:35 +0000
71+++ debian/changelog 2016-03-11 18:12:46 +0000
72@@ -1,3 +1,100 @@
73+unity8 (8.13+15.04.20150914-0ubuntu1) UNRELEASED; urgency=medium
74+
75+ * bump version to fix OOBE build
76+
77+ -- Lukas Tinkl <ltinkl@canonical.com> Mon, 14 Sep 2015 19:19:23 +0200
78+
79+unity8 (8.11+16.04.20160310.4-0ubuntu1) xenial; urgency=medium
80+
81+ [ Albert Astals Cid ]
82+ * Add context for Re-dock as asked by translators (LP: #1534608)
83+ * Add emblem to the preview header widget (LP: #1424720)
84+ * Add haptics to ScopesListCategoryItem buttons
85+ * Audio Cards: Make some of the image loading async (LP: #1533432)
86+ * Do not create fallback code for the card tool fake card (LP:
87+ #1545865)
88+ * Fix resizing the dash bringing temp scopes size out of sync (LP:
89+ #1543130)
90+ * Minor fixes for unity-scope-tool
91+ * Resolve title alignment on card creator time instead of on runtime
92+ * Use fixedHeaderHeight only in the non cardtool cards
93+ * Use the new undeprecated connectivityqt::Connectivity
94+ * asynchronous is only false on the fake card in cardtool
95+ * clazy fixes
96+
97+ [ Albert Astals Cid, CI Train Bot ]
98+ * click scope: Add the else branch so we reset the card size in all
99+ situations
100+
101+ [ Andrea Cimitan ]
102+ * PreviewSharing widget now accepts both string and array of
103+ widgetData["share-data"]["uri"] (LP: #1549056)
104+ * Update AP tests for new single preview
105+ * Use Text.Wrap for body notification text (LP: #1544909)
106+
107+ [ Andrea Cimitan, Lukáš Tinkl, Michael Zanetti, Nick Dedekind ]
108+ * some fixes for the new palette (LP: #1554616)
109+
110+ [ CI Train Bot ]
111+ * Resync trunk.
112+ * Update translation template
113+
114+ [ CI Train Bot, Daniel d'Andrada ]
115+ * Ensure the QML engine doesn't delete our mock MirSurfaces on its
116+ own.
117+
118+ [ Daniel d'Andrada ]
119+ * tst_Shell: Remove unused qml items
120+
121+ [ Josh Arenson ]
122+ * Allow the shell to blacklist input devices and force the OSK shown.
123+ (LP: #1542224)
124+
125+ [ Lukáš Tinkl ]
126+ * Disallow resizing windows up, past the Panel (LP: #1544766)
127+ * Elide the window title not to let it overflow into the indicators
128+ area (LP: #1535767)
129+ * Enable the PIN lockscreen to be used with a HW keyboard (LP:
130+ #1550359)
131+ * Fix tiny windows when switching stages
132+ * Provide a range of ports to QML JS Debugger
133+ * Watch for launcher item icon changes (LP: #1543290)
134+
135+ [ Michael Terry ]
136+ * Proxy more mouse and touchpad properties to USC (LP: #1540398) (LP:
137+ #1543344, #1540398)
138+ * Refactor the AccountsService plugin and make it slightly faster.
139+ * To let the user log in if a mouse is connected, hide the greeter
140+ cover page on a mouse click (but NOT a touch click). (LP: #1540497)
141+ * Watch AccountsService for changes to the user's real name. This was
142+ preventing us from noticing when the user set their name in the
143+ welcome wizard.
144+
145+ [ Michael Zanetti ]
146+ * Allow alt+tabbing in staged mode too (LP: #1540502)
147+ * Allow invoking the staged mode spreads by mouse right edge pushes
148+ too (LP: #1540392)
149+ * Allow loading the device configuration from an external file
150+ * Implement Launcher's keyboard navigation and updated pip design
151+ * Make launcher scalable, allow it locking (LP: #1511015)
152+ * Properly parent launcher items in all cases (LP: #1495732)
153+ * Read inputMethod surface from the new property int QtMir (LP:
154+ #1545286)
155+ * Some visual updates and rotation lock for the virtual touchpad (LP:
156+ #1549087)
157+ * Visual updates for the windowed spread (LP: #1488148)
158+ * stabilize swipeAwayGreeter()
159+
160+ [ Michał Sawicz ]
161+ * Add udev rules to make sure we have access to uinput
162+ * Make dash respawn indefinitely (LP: #1550056)
163+ * Use dpkg-architecture, not arch, to disable touch emulation
164+
165+ [ Vesa Rautiainen ]
166+ * Fixing the vertical position of desktop spread item icon.
167+
168+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 10 Mar 2016 22:44:16 +0000
169+
170 unity8 (8.11+16.04.20160308-0ubuntu1) xenial; urgency=medium
171
172 [ Albert Astals Cid ]
173
174=== modified file 'debian/control'
175--- debian/control 2016-03-04 21:03:43 +0000
176+++ debian/control 2016-03-11 18:12:46 +0000
177@@ -8,13 +8,14 @@
178 doxyqml,
179 # To allow cross-compiling to work, we also must append :native
180 # to g++ so we don't try to run armhf g++
181-# on an x86 CPU for eaxmple, when cross-compiling.
182+# on an x86 CPU for example, when cross-compiling.
183 g++:native,
184 libandroid-properties-dev,
185 graphviz,
186 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
187- libconnectivity-qt1-dev,
188+ libconnectivity-qt1-dev (>= 0.7.1),
189 libevdev-dev,
190+ libgeonames-dev (>= 0.2),
191 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
192 libgl1-mesa-dri,
193 libgles2-mesa-dev[armhf],
194@@ -55,7 +56,7 @@
195 qtdeclarative5-qtmultimedia-plugin (>= 5.4.1-1ubuntu19~overlay2),
196 qtdeclarative5-ubuntu-content1,
197 qtdeclarative5-ubuntu-settings-components (>= 0.7),
198- qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1796) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1796),
199+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
200 qtdeclarative5-ubuntu-web-plugin,
201 ttf-ubuntu-font-family,
202 Standards-Version: 3.9.4
203@@ -70,7 +71,7 @@
204 Package: indicators-client
205 Architecture: amd64 armhf i386
206 Depends: qmenumodel-qml (>= 0.2.9),
207- qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1796) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1796),
208+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
209 unity8 (= ${binary:Version}),
210 ${misc:Depends},
211 ${shlibs:Depends},
212@@ -101,7 +102,6 @@
213 qml-module-qt-labs-folderlistmodel,
214 qml-module-qtquick-xmllistmodel,
215 qml-module-qtsysteminfo,
216- qtdeclarative5-gsettings1.0,
217 qtdeclarative5-qtmir-plugin (>= 0.4.5),
218 qtdeclarative5-ubuntu-telephony0.1,
219 qtdeclarative5-ubuntu-web-plugin,
220@@ -128,7 +128,7 @@
221 Depends: qml-module-qtquick-layouts,
222 qtdeclarative5-ubuntu-settings-components (>= 0.7),
223 qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
224- qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1796) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1796),
225+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
226 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
227 ubuntu-thumbnailer-impl-0,
228 unity-application-impl-13,
229@@ -158,7 +158,7 @@
230 python3-fixtures,
231 python3-gi,
232 qttestability-autopilot (>= 1.4),
233- ubuntu-ui-toolkit-autopilot (>= 1.3.1796),
234+ ubuntu-ui-toolkit-autopilot (>= 1.3.1845),
235 unity-scope-click,
236 unity8 (= ${source:Version}),
237 unity8-fake-env (= ${source:Version}),
238@@ -192,6 +192,8 @@
239 libhardware2,
240 pay-service,
241 unity-schemas (>= 7.3.1+14.10.20140915),
242+ qtdeclarative5-gsettings1.0,
243+ qml-module-qtmultimedia,
244 ${misc:Depends},
245 ${shlibs:Depends},
246 Provides: unity-launcher-impl,
247
248=== added file 'debian/unity8-common.udev'
249--- debian/unity8-common.udev 1970-01-01 00:00:00 +0000
250+++ debian/unity8-common.udev 2016-03-11 18:12:46 +0000
251@@ -0,0 +1,2 @@
252+# Make local foreground session able to inject input
253+KERNEL=="uinput", SUBSYSTEM=="misc", TAG+="uaccess"
254
255=== modified file 'debian/unity8-doc.install'
256--- debian/unity8-doc.install 2014-01-30 22:32:37 +0000
257+++ debian/unity8-doc.install 2016-03-11 18:12:46 +0000
258@@ -1,1 +1,2 @@
259+doc/devices.conf usr/share/doc/unity8/
260 usr/share/doc/unity8/*
261
262=== added file 'doc/devices.conf'
263--- doc/devices.conf 1970-01-01 00:00:00 +0000
264+++ doc/devices.conf 2016-03-11 18:12:46 +0000
265@@ -0,0 +1,30 @@
266+# This file can hold multiple device configs. Devices are separated by sections.
267+#
268+# SupportedOrientations holds a list of all enabled orientations. A standard
269+# phone will usually have Portrait,Landcape,InvertedLandscape in order to
270+# disable upside down usage.
271+#
272+# PrimaryOrientation gives the orientation the device will start up with
273+# when there is no orientations sensor input available (yet) or lock to
274+# when an application specifies to be locked to PrimaryOrientation.
275+#
276+# The other Orientation settings can be used to re-map the orientations.
277+# A device might be used with different orientations than how the screen
278+# is physically mounted on the hardware.
279+#
280+# Category can be phone, tablet, or desktop. This option determines
281+# whether the side stage is shown (tablet) or not (phone). Using
282+# desktop will load the shell in windowed mode. Note that the user
283+# can override/change this by connecting input hardware or change
284+# user settings.
285+#
286+# Any options not listed will default to the values of the example below.
287+
288+[devicename]
289+SupportedOrientations=Portrait,InvertedPortrait,Landscape,InvertedLandscape
290+PrimaryOrientation=PrimaryOrienation
291+PortraitOrientation=Portrait
292+InvertedPortraitOrientation=InvertedPortrait
293+LandscapeOrientation=Landscape
294+InvertedLandscapeOrientation=InvertedLandscape
295+Category=phone
296
297=== modified file 'plugins/AccountsService/AccountsService.cpp'
298--- plugins/AccountsService/AccountsService.cpp 2016-01-21 21:04:00 +0000
299+++ plugins/AccountsService/AccountsService.cpp 2016-03-11 18:12:46 +0000
300@@ -1,5 +1,5 @@
301 /*
302- * Copyright (C) 2013 Canonical, Ltd.
303+ * Copyright (C) 2013, 2015 Canonical, Ltd.
304 *
305 * This program is free software; you can redistribute it and/or modify
306 * it under the terms of the GNU General Public License as published by
307@@ -12,8 +12,6 @@
308 *
309 * You should have received a copy of the GNU General Public License
310 * along with this program. If not, see <http://www.gnu.org/licenses/>.
311- *
312- * Author: Michael Terry <michael.terry@canonical.com>
313 */
314
315 #include "AccountsService.h"
316@@ -24,17 +22,55 @@
317 #include <QStringList>
318 #include <QDebug>
319
320+#define IFACE_ACCOUNTS_USER QStringLiteral("org.freedesktop.Accounts.User")
321+#define IFACE_LOCATION_HERE QStringLiteral("com.ubuntu.location.providers.here.AccountsService")
322+#define IFACE_UBUNTU_INPUT QStringLiteral("com.ubuntu.AccountsService.Input")
323+#define IFACE_UBUNTU_SECURITY QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy")
324+#define IFACE_UBUNTU_SECURITY_OLD QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy")
325+#define IFACE_UNITY QStringLiteral("com.canonical.unity.AccountsService")
326+#define IFACE_UNITY_PRIVATE QStringLiteral("com.canonical.unity.AccountsService.Private")
327+
328+#define PROP_BACKGROUND_FILE QStringLiteral("BackgroundFile")
329+#define PROP_DEMO_EDGES QStringLiteral("demo-edges")
330+#define PROP_DEMO_EDGES_COMPLETED QStringLiteral("DemoEdgesCompleted")
331+#define PROP_EMAIL QStringLiteral("Email")
332+#define PROP_ENABLE_INDICATORS_WHILE_LOCKED QStringLiteral("EnableIndicatorsWhileLocked")
333+#define PROP_ENABLE_LAUNCHER_WHILE_LOCKED QStringLiteral("EnableLauncherWhileLocked")
334+#define PROP_FAILED_LOGINS QStringLiteral("FailedLogins")
335+#define PROP_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted")
336+#define PROP_LICENSE_BASE_PATH QStringLiteral("LicenseBasePath")
337+#define PROP_MOUSE_CURSOR_SPEED QStringLiteral("MouseCursorSpeed")
338+#define PROP_MOUSE_DOUBLE_CLICK_SPEED QStringLiteral("MouseDoubleClickSpeed")
339+#define PROP_MOUSE_PRIMARY_BUTTON QStringLiteral("MousePrimaryButton")
340+#define PROP_MOUSE_SCROLL_SPEED QStringLiteral("MouseScrollSpeed")
341+#define PROP_PASSWORD_DISPLAY_HINT QStringLiteral("PasswordDisplayHint")
342+#define PROP_REAL_NAME QStringLiteral("RealName")
343+#define PROP_STATS_WELCOME_SCREEN QStringLiteral("StatsWelcomeScreen")
344+#define PROP_TOUCHPAD_CURSOR_SPEED QStringLiteral("TouchpadCursorSpeed")
345+#define PROP_TOUCHPAD_DISABLE_WHILE_TYPING QStringLiteral("TouchpadDisableWhileTyping")
346+#define PROP_TOUCHPAD_DISABLE_WITH_MOUSE QStringLiteral("TouchpadDisableWithMouse")
347+#define PROP_TOUCHPAD_DOUBLE_CLICK_SPEED QStringLiteral("TouchpadDoubleClickSpeed")
348+#define PROP_TOUCHPAD_PRIMARY_BUTTON QStringLiteral("TouchpadPrimaryButton")
349+#define PROP_TOUCHPAD_SCROLL_SPEED QStringLiteral("TouchpadScrollSpeed")
350+#define PROP_TOUCHPAD_TAP_TO_CLICK QStringLiteral("TouchpadTapToClick")
351+#define PROP_TOUCHPAD_TWO_FINGER_SCROLL QStringLiteral("TouchpadTwoFingerScroll")
352+
353+
354+QVariant primaryButtonConverter(const QVariant &value)
355+{
356+ QString stringValue = value.toString();
357+ if (stringValue == "left") {
358+ return QVariant::fromValue(0);
359+ } else if (stringValue == "right") {
360+ return QVariant::fromValue(1); // Mir is less clear on this -- any non-zero value is the same
361+ } else {
362+ return QVariant::fromValue(0); // default to left
363+ }
364+}
365+
366 AccountsService::AccountsService(QObject* parent, const QString &user)
367- : QObject(parent),
368- m_service(new AccountsServiceDBusAdaptor(this)),
369- m_demoEdges(false),
370- m_enableLauncherWhileLocked(false),
371- m_enableIndicatorsWhileLocked(false),
372- m_statsWelcomeScreen(false),
373- m_passwordDisplayHint(Keyboard),
374- m_failedLogins(0),
375- m_hereEnabled(false),
376- m_hereLicensePath() // null means not set yet
377+ : QObject(parent)
378+ , m_service(new AccountsServiceDBusAdaptor(this))
379 {
380 m_unityInput = new QDBusInterface(QStringLiteral("com.canonical.Unity.Input"),
381 QStringLiteral("/com/canonical/Unity/Input"),
382@@ -44,6 +80,46 @@
383 connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged);
384 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged);
385
386+ registerProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE, QStringLiteral("backgroundFileChanged"));
387+ registerProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL, QStringLiteral("emailChanged"));
388+ registerProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME, QStringLiteral("realNameChanged"));
389+ registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, QStringLiteral("hereEnabledChanged"));
390+ registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH, QStringLiteral("hereLicensePathChanged"));
391+ registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED, QStringLiteral("enableLauncherWhileLockedChanged"));
392+ registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED, QStringLiteral("enableIndicatorsWhileLockedChanged"));
393+ registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral("passwordDisplayHintChanged"));
394+ registerProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN, QStringLiteral("statsWelcomeScreenChanged"));
395+ registerProperty(IFACE_UNITY, PROP_DEMO_EDGES, QStringLiteral("demoEdgesChanged"));
396+ registerProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, QStringLiteral("demoEdgesCompletedChanged"));
397+ registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, QStringLiteral("failedLoginsChanged"));
398+
399+ registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
400+ m_unityInput, QStringLiteral("setMouseCursorSpeed"));
401+ registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_DOUBLE_CLICK_SPEED,
402+ m_unityInput, QStringLiteral("setMouseDoubleClickSpeed"));
403+ registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_PRIMARY_BUTTON,
404+ m_unityInput, QStringLiteral("setMousePrimaryButton"),
405+ primaryButtonConverter);
406+ registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_SCROLL_SPEED,
407+ m_unityInput, QStringLiteral("setMouseScrollSpeed"));
408+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_CURSOR_SPEED,
409+ m_unityInput, QStringLiteral("setTouchpadCursorSpeed"));
410+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_SCROLL_SPEED,
411+ m_unityInput, QStringLiteral("setTouchpadScrollSpeed"));
412+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WHILE_TYPING,
413+ m_unityInput, QStringLiteral("setTouchpadDisableWhileTyping"));
414+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WITH_MOUSE,
415+ m_unityInput, QStringLiteral("setTouchpadDisableWithMouse"));
416+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DOUBLE_CLICK_SPEED,
417+ m_unityInput, QStringLiteral("setTouchpadDoubleClickSpeed"));
418+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_PRIMARY_BUTTON,
419+ m_unityInput, QStringLiteral("setTouchpadPrimaryButton"),
420+ primaryButtonConverter);
421+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TAP_TO_CLICK,
422+ m_unityInput, QStringLiteral("setTouchpadTapToClick"));
423+ registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TWO_FINGER_SCROLL,
424+ m_unityInput, QStringLiteral("setTouchpadTwoFingerScroll"));
425+
426 setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER")));
427 }
428
429@@ -57,410 +133,236 @@
430 if (user.isEmpty() || m_user == user)
431 return;
432
433+ bool wasEmpty = m_user.isEmpty();
434+
435 m_user = user;
436 Q_EMIT userChanged();
437
438- updateDemoEdges(false);
439- updateEnableLauncherWhileLocked(false);
440- updateEnableIndicatorsWhileLocked(false);
441- updateBackgroundFile(false);
442- updateMouseCursorSpeed();
443- updateTouchpadCursorSpeed();
444- updateStatsWelcomeScreen(false);
445- updatePasswordDisplayHint(false);
446- updateFailedLogins(false);
447- updateHereEnabled(false);
448- updateHereLicensePath(false);
449+ // Do the first update synchronously, as a cheap way to block rendering
450+ // until we have the right values on bootup.
451+ refresh(!wasEmpty);
452 }
453
454 bool AccountsService::demoEdges() const
455 {
456- return m_demoEdges;
457+ auto value = getProperty(IFACE_UNITY, PROP_DEMO_EDGES);
458+ return value.toBool();
459 }
460
461 void AccountsService::setDemoEdges(bool demoEdges)
462 {
463- if (m_demoEdges != demoEdges) {
464- m_demoEdges = demoEdges;
465- m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService"), QStringLiteral("demo-edges"), demoEdges);
466-
467- Q_EMIT demoEdgesChanged();
468+ setProperty(IFACE_UNITY, PROP_DEMO_EDGES, demoEdges);
469+}
470+
471+QStringList AccountsService::demoEdgesCompleted() const
472+{
473+ auto value = getProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED);
474+ return value.toStringList();
475+}
476+
477+void AccountsService::markDemoEdgeCompleted(const QString &edge)
478+{
479+ auto currentList = demoEdgesCompleted();
480+ if (!currentList.contains(edge)) {
481+ setProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, currentList << edge);
482 }
483 }
484
485 bool AccountsService::enableLauncherWhileLocked() const
486 {
487- return m_enableLauncherWhileLocked;
488+ auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED);
489+ return value.toBool();
490 }
491
492 bool AccountsService::enableIndicatorsWhileLocked() const
493 {
494- return m_enableIndicatorsWhileLocked;
495+ auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED);
496+ return value.toBool();
497 }
498
499 QString AccountsService::backgroundFile() const
500 {
501- return m_backgroundFile;
502+ auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE);
503+ return value.toString();
504 }
505
506 bool AccountsService::statsWelcomeScreen() const
507 {
508- return m_statsWelcomeScreen;
509+ auto value = getProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN);
510+ return value.toBool();
511 }
512
513 AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
514 {
515- return m_passwordDisplayHint;
516+ auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT);
517+ return (PasswordDisplayHint)value.toInt();
518 }
519
520 bool AccountsService::hereEnabled() const
521 {
522- return m_hereEnabled;
523+ auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED);
524+ return value.toBool();
525 }
526
527 void AccountsService::setHereEnabled(bool enabled)
528 {
529- if (m_hereEnabled != enabled) {
530- m_hereEnabled = enabled;
531- m_service->setUserPropertyAsync(m_user, QStringLiteral("com.ubuntu.location.providers.here.AccountsService"), QStringLiteral("LicenseAccepted"), enabled);
532-
533- Q_EMIT hereEnabledChanged();
534- }
535+ setProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, enabled);
536 }
537
538 QString AccountsService::hereLicensePath() const
539 {
540- return m_hereLicensePath;
541+ auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
542+ QString hereLicensePath = value.toString();
543+ if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
544+ hereLicensePath = QStringLiteral("");
545+ return hereLicensePath;
546 }
547
548 bool AccountsService::hereLicensePathValid() const
549 {
550- return !m_hereLicensePath.isNull();
551-}
552-
553-void AccountsService::updateDemoEdges(bool async)
554-{
555- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
556- QStringLiteral("com.canonical.unity.AccountsService"),
557- QStringLiteral("demo-edges"));
558- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
559-
560- connect(watcher, &QDBusPendingCallWatcher::finished,
561- this, [this](QDBusPendingCallWatcher* watcher) {
562-
563- QDBusPendingReply<QDBusVariant> reply = *watcher;
564- watcher->deleteLater();
565- if (reply.isError()) {
566- qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message();
567- return;
568- }
569-
570- auto demoEdges = reply.value().variant().toBool();
571- if (m_demoEdges != demoEdges) {
572- m_demoEdges = demoEdges;
573- Q_EMIT demoEdgesChanged();
574- }
575- });
576- if (!async) {
577- watcher->waitForFinished();
578- delete watcher;
579- }
580-}
581-
582-void AccountsService::updateEnableLauncherWhileLocked(bool async)
583-{
584- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
585- QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
586- QStringLiteral("EnableLauncherWhileLocked"));
587- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
588-
589- connect(watcher, &QDBusPendingCallWatcher::finished,
590- this, [this](QDBusPendingCallWatcher* watcher) {
591-
592- QDBusPendingReply<QVariant> reply = *watcher;
593- watcher->deleteLater();
594- if (reply.isError()) {
595- qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message();
596- return;
597- }
598-
599- const bool enableLauncherWhileLocked = reply.value().toBool();
600- if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) {
601- m_enableLauncherWhileLocked = enableLauncherWhileLocked;
602- Q_EMIT enableLauncherWhileLockedChanged();
603- }
604- });
605- if (!async) {
606- watcher->waitForFinished();
607- delete watcher;
608- }
609-}
610-
611-void AccountsService::updateEnableIndicatorsWhileLocked(bool async)
612-{
613- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
614- QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
615- QStringLiteral("EnableIndicatorsWhileLocked"));
616- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
617-
618- connect(watcher, &QDBusPendingCallWatcher::finished,
619- this, [this](QDBusPendingCallWatcher* watcher) {
620-
621- QDBusPendingReply<QVariant> reply = *watcher;
622- watcher->deleteLater();
623- if (reply.isError()) {
624- qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message();
625- return;
626- }
627-
628- const bool enableIndicatorsWhileLocked = reply.value().toBool();
629- if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) {
630- m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked;
631- Q_EMIT enableIndicatorsWhileLockedChanged();
632- }
633- });
634- if (!async) {
635- watcher->waitForFinished();
636- delete watcher;
637- }
638-}
639-
640-void AccountsService::updateBackgroundFile(bool async)
641-{
642- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
643- QStringLiteral("org.freedesktop.Accounts.User"),
644- QStringLiteral("BackgroundFile"));
645- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
646-
647- connect(watcher, &QDBusPendingCallWatcher::finished,
648- this, [this](QDBusPendingCallWatcher* watcher) {
649-
650- QDBusPendingReply<QVariant> reply = *watcher;
651- watcher->deleteLater();
652- if (reply.isError()) {
653- qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message();
654- return;
655- }
656-
657- const QString backgroundFile = reply.value().toString();
658- if (m_backgroundFile != backgroundFile) {
659- m_backgroundFile = backgroundFile;
660- Q_EMIT backgroundFileChanged();
661- }
662- });
663- if (!async) {
664- watcher->waitForFinished();
665- delete watcher;
666- }
667-}
668-
669-void AccountsService::updateMouseCursorSpeed()
670-{
671- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
672- QStringLiteral("com.ubuntu.AccountsService.Input"),
673- QStringLiteral("MouseCursorSpeed"));
674- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
675-
676- connect(watcher, &QDBusPendingCallWatcher::finished,
677- this, [this](QDBusPendingCallWatcher* watcher) {
678-
679- QDBusPendingReply<QVariant> reply = *watcher;
680- watcher->deleteLater();
681- if (reply.isError()) {
682- qWarning() << "Failed to get 'MouseCursorSpeed' property - " << reply.error().message();
683- return;
684- }
685-
686- // Merely proxy this along to USC. We don't care about keeping a copy
687- // or exporting it internally.
688- m_unityInput->asyncCall(QStringLiteral("setMouseCursorSpeed"), reply.value());
689- });
690-}
691-
692-void AccountsService::updateTouchpadCursorSpeed()
693-{
694- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
695- QStringLiteral("com.ubuntu.AccountsService.Input"),
696- QStringLiteral("TouchpadCursorSpeed"));
697- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
698-
699- connect(watcher, &QDBusPendingCallWatcher::finished,
700- this, [this](QDBusPendingCallWatcher* watcher) {
701-
702- QDBusPendingReply<QVariant> reply = *watcher;
703- watcher->deleteLater();
704- if (reply.isError()) {
705- qWarning() << "Failed to get 'TouchpadCursorSpeed' property - " << reply.error().message();
706- return;
707- }
708-
709- // Merely proxy this along to USC. We don't care about keeping a copy
710- // or exporting it internally.
711- m_unityInput->asyncCall(QStringLiteral("setTouchpadCursorSpeed"), reply.value());
712- });
713-}
714-
715-void AccountsService::updateStatsWelcomeScreen(bool async)
716-{
717- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
718- QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy"),
719- QStringLiteral("StatsWelcomeScreen"));
720- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
721-
722- connect(watcher, &QDBusPendingCallWatcher::finished,
723- this, [this](QDBusPendingCallWatcher* watcher) {
724-
725- QDBusPendingReply<QVariant> reply = *watcher;
726- watcher->deleteLater();
727- if (reply.isError()) {
728- qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message();
729- return;
730- }
731-
732- const bool statsWelcomeScreen = reply.value().toBool();
733- if (m_statsWelcomeScreen != statsWelcomeScreen) {
734- m_statsWelcomeScreen = statsWelcomeScreen;
735- Q_EMIT statsWelcomeScreenChanged();
736- }
737- });
738- if (!async) {
739- watcher->waitForFinished();
740- delete watcher;
741- }
742-}
743-
744-void AccountsService::updatePasswordDisplayHint(bool async)
745-{
746- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
747- QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"),
748- QStringLiteral("PasswordDisplayHint"));
749- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
750-
751- connect(watcher, &QDBusPendingCallWatcher::finished,
752- this, [this](QDBusPendingCallWatcher* watcher) {
753-
754- QDBusPendingReply<QVariant> reply = *watcher;
755- watcher->deleteLater();
756- if (reply.isError()) {
757- qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message();
758- return;
759- }
760-
761- const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt();
762- if (m_passwordDisplayHint != passwordDisplayHint) {
763- m_passwordDisplayHint = passwordDisplayHint;
764- Q_EMIT passwordDisplayHintChanged();
765- }
766- });
767- if (!async) {
768- watcher->waitForFinished();
769- delete watcher;
770- }
771-}
772-
773-void AccountsService::updateFailedLogins(bool async)
774-{
775- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
776- QStringLiteral("com.canonical.unity.AccountsService.Private"),
777- QStringLiteral("FailedLogins"));
778- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
779-
780- connect(watcher, &QDBusPendingCallWatcher::finished,
781- this, [this](QDBusPendingCallWatcher* watcher) {
782-
783- QDBusPendingReply<QVariant> reply = *watcher;
784- watcher->deleteLater();
785- if (reply.isError()) {
786- qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message();
787- return;
788- }
789-
790- const uint failedLogins = reply.value().toUInt();
791- if (m_failedLogins != failedLogins) {
792- m_failedLogins = failedLogins;
793- Q_EMIT failedLoginsChanged();
794- }
795- });
796- if (!async) {
797- watcher->waitForFinished();
798- delete watcher;
799- }
800-}
801-
802-void AccountsService::updateHereEnabled(bool async)
803-{
804- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
805- QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
806- QStringLiteral("LicenseAccepted"));
807- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
808-
809- connect(watcher, &QDBusPendingCallWatcher::finished,
810- this, [this](QDBusPendingCallWatcher* watcher) {
811-
812- QDBusPendingReply<QVariant> reply = *watcher;
813- watcher->deleteLater();
814- if (reply.isError()) {
815- qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message();
816- return;
817- }
818-
819- const bool hereEnabled = reply.value().toBool();
820- if (m_hereEnabled != hereEnabled) {
821- m_hereEnabled = hereEnabled;
822- Q_EMIT hereEnabledChanged();
823- }
824- });
825- if (!async) {
826- watcher->waitForFinished();
827- delete watcher;
828- }
829-}
830-
831-void AccountsService::updateHereLicensePath(bool async)
832-{
833- QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
834- QStringLiteral("com.ubuntu.location.providers.here.AccountsService"),
835- QStringLiteral("LicenseBasePath"));
836- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
837-
838- connect(watcher, &QDBusPendingCallWatcher::finished,
839- this, [this](QDBusPendingCallWatcher* watcher) {
840-
841- QDBusPendingReply<QVariant> reply = *watcher;
842- watcher->deleteLater();
843- if (reply.isError()) {
844- qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message();
845- return;
846- }
847-
848- QString hereLicensePath = reply.value().toString();
849- if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
850- hereLicensePath = QLatin1String("");
851-
852- if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) {
853- m_hereLicensePath = hereLicensePath;
854- Q_EMIT hereLicensePathChanged();
855- }
856- });
857- if (!async) {
858- watcher->waitForFinished();
859- delete watcher;
860- }
861+ auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
862+ return !value.toString().isNull();
863+}
864+
865+QString AccountsService::realName() const
866+{
867+ auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME);
868+ return value.toString();
869+}
870+
871+void AccountsService::setRealName(const QString &realName)
872+{
873+ setProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME, realName);
874+}
875+
876+QString AccountsService::email() const
877+{
878+ auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL);
879+ return value.toString();
880+}
881+
882+void AccountsService::setEmail(const QString &email)
883+{
884+ setProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL, email);
885 }
886
887 uint AccountsService::failedLogins() const
888 {
889- return m_failedLogins;
890+ return getProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS).toUInt();
891 }
892
893 void AccountsService::setFailedLogins(uint failedLogins)
894 {
895- if (m_failedLogins != failedLogins) {
896- m_failedLogins = failedLogins;
897- m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService.Private"), QStringLiteral("FailedLogins"), failedLogins);
898-
899- Q_EMIT failedLoginsChanged();
900- }
901+ setProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, failedLogins);
902+}
903+
904+// ====================================================
905+// Everything below this line is generic helper methods
906+// ====================================================
907+
908+void AccountsService::emitChangedForProperty(const QString &interface, const QString &property)
909+{
910+ QString signalName = m_properties[interface][property].signal;
911+ QMetaObject::invokeMethod(this, signalName.toUtf8().data());
912+}
913+
914+QVariant AccountsService::getProperty(const QString &interface, const QString &property) const
915+{
916+ return m_properties[interface][property].value;
917+}
918+
919+void AccountsService::setProperty(const QString &interface, const QString &property, const QVariant &value)
920+{
921+ if (m_properties[interface][property].value != value) {
922+ m_properties[interface][property].value = value;
923+ m_service->setUserPropertyAsync(m_user, interface, property, value);
924+ emitChangedForProperty(interface, property);
925+ }
926+}
927+
928+void AccountsService::updateCache(const QString &interface, const QString &property, const QVariant &value)
929+{
930+ PropertyInfo &info = m_properties[interface][property];
931+
932+ if (info.proxyInterface) {
933+ QVariant finalValue;
934+ if (info.proxyConverter) {
935+ finalValue = info.proxyConverter(value);
936+ } else {
937+ finalValue = value;
938+ }
939+ info.proxyInterface->asyncCall(info.proxyMethod, finalValue);
940+ return; // don't bother saving a copy
941+ }
942+
943+ if (info.value != value) {
944+ info.value = value;
945+ emitChangedForProperty(interface, property);
946+ }
947+}
948+
949+void AccountsService::updateProperty(const QString &interface, const QString &property)
950+{
951+ QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user,
952+ interface,
953+ property);
954+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
955+
956+ connect(watcher, &QDBusPendingCallWatcher::finished,
957+ this, [this, interface, property](QDBusPendingCallWatcher* watcher) {
958+
959+ QDBusPendingReply<QVariant> reply = *watcher;
960+ watcher->deleteLater();
961+ if (reply.isError()) {
962+ qWarning() << "Failed to get '" << property << "' property:" << reply.error().message();
963+ return;
964+ }
965+
966+ updateCache(interface, property, reply.value());
967+ });
968+}
969+
970+void AccountsService::updateAllProperties(const QString &interface, bool async)
971+{
972+ QDBusPendingCall pendingReply = m_service->getAllPropertiesAsync(m_user,
973+ interface);
974+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this);
975+
976+ connect(watcher, &QDBusPendingCallWatcher::finished,
977+ this, [this, interface](QDBusPendingCallWatcher* watcher) {
978+
979+ QDBusPendingReply< QHash<QString, QVariant> > reply = *watcher;
980+ watcher->deleteLater();
981+ if (reply.isError()) {
982+ qWarning() << "Failed to get all properties for" << interface << ":" << reply.error().message();
983+ return;
984+ }
985+
986+ auto valueHash = reply.value();
987+ auto i = valueHash.constBegin();
988+ while (i != valueHash.constEnd()) {
989+ updateCache(interface, i.key(), i.value());
990+ ++i;
991+ }
992+ });
993+ if (!async) {
994+ watcher->waitForFinished();
995+ }
996+}
997+
998+void AccountsService::registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter)
999+{
1000+ registerProperty(interface, property, nullptr);
1001+
1002+ m_properties[interface][property].proxyInterface = iface;
1003+ m_properties[interface][property].proxyMethod = method;
1004+ m_properties[interface][property].proxyConverter = converter;
1005+}
1006+
1007+void AccountsService::registerProperty(const QString &interface, const QString &property, const QString &signal)
1008+{
1009+ m_properties[interface][property] = PropertyInfo();
1010+ m_properties[interface][property].signal = signal;
1011 }
1012
1013 void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
1014@@ -469,42 +371,13 @@
1015 return;
1016 }
1017
1018- if (interface == QLatin1String("com.canonical.unity.AccountsService")) {
1019- if (changed.contains(QStringLiteral("demo-edges"))) {
1020- updateDemoEdges();
1021- }
1022- } else if (interface == QLatin1String("com.canonical.unity.AccountsService.Private")) {
1023- if (changed.contains(QStringLiteral("FailedLogins"))) {
1024- updateFailedLogins();
1025- }
1026- } else if (interface == QLatin1String("com.ubuntu.AccountsService.Input")) {
1027- if (changed.contains(QStringLiteral("MouseCursorSpeed"))) {
1028- updateMouseCursorSpeed();
1029- }
1030- if (changed.contains(QStringLiteral("TouchpadCursorSpeed"))) {
1031- updateTouchpadCursorSpeed();
1032- }
1033- } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) {
1034- if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) {
1035- updateStatsWelcomeScreen();
1036- }
1037- } else if (interface == QLatin1String("com.ubuntu.AccountsService.SecurityPrivacy")) {
1038- if (changed.contains(QStringLiteral("PasswordDisplayHint"))) {
1039- updatePasswordDisplayHint();
1040- }
1041- if (changed.contains(QStringLiteral("EnableLauncherWhileLocked"))) {
1042- updateEnableLauncherWhileLocked();
1043- }
1044- if (changed.contains(QStringLiteral("EnableIndicatorsWhileLocked"))) {
1045- updateEnableIndicatorsWhileLocked();
1046- }
1047- } else if (interface == QLatin1String("com.ubuntu.location.providers.here.AccountsService")) {
1048- if (changed.contains(QStringLiteral("LicenseAccepted"))) {
1049- updateHereEnabled();
1050- }
1051- if (changed.contains(QStringLiteral("LicenseBasePath"))) {
1052- updateHereLicensePath();
1053- }
1054+ auto propHash = m_properties.value(interface);
1055+ auto i = propHash.constBegin();
1056+ while (i != propHash.constEnd()) {
1057+ if (changed.contains(i.key())) {
1058+ updateProperty(interface, i.key());
1059+ }
1060+ ++i;
1061 }
1062 }
1063
1064@@ -514,6 +387,20 @@
1065 return;
1066 }
1067
1068- // Standard properties might have changed
1069- updateBackgroundFile();
1070+ // Any of the standard properties might have changed!
1071+ auto propHash = m_properties.value(IFACE_ACCOUNTS_USER);
1072+ auto i = propHash.constBegin();
1073+ while (i != propHash.constEnd()) {
1074+ updateProperty(IFACE_ACCOUNTS_USER, i.key());
1075+ ++i;
1076+ }
1077+}
1078+
1079+void AccountsService::refresh(bool async)
1080+{
1081+ auto i = m_properties.constBegin();
1082+ while (i != m_properties.constEnd()) {
1083+ updateAllProperties(i.key(), async);
1084+ ++i;
1085+ }
1086 }
1087
1088=== modified file 'plugins/AccountsService/AccountsService.h'
1089--- plugins/AccountsService/AccountsService.h 2016-01-21 21:04:00 +0000
1090+++ plugins/AccountsService/AccountsService.h 2016-03-11 18:12:46 +0000
1091@@ -1,5 +1,5 @@
1092 /*
1093- * Copyright (C) 2013 Canonical, Ltd.
1094+ * Copyright (C) 2013, 2015 Canonical, Ltd.
1095 *
1096 * This program is free software; you can redistribute it and/or modify
1097 * it under the terms of the GNU General Public License as published by
1098@@ -12,15 +12,16 @@
1099 *
1100 * You should have received a copy of the GNU General Public License
1101 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1102- *
1103- * Authors: Michael Terry <michael.terry@canonical.com>
1104 */
1105
1106 #ifndef UNITY_ACCOUNTSSERVICE_H
1107 #define UNITY_ACCOUNTSSERVICE_H
1108
1109+#include <QHash>
1110 #include <QObject>
1111 #include <QString>
1112+#include <QStringList>
1113+#include <QVariant>
1114
1115 class AccountsServiceDBusAdaptor;
1116 class QDBusInterface;
1117@@ -37,6 +38,9 @@
1118 READ demoEdges
1119 WRITE setDemoEdges
1120 NOTIFY demoEdgesChanged)
1121+ Q_PROPERTY (QStringList demoEdgesCompleted
1122+ READ demoEdgesCompleted
1123+ NOTIFY demoEdgesCompletedChanged)
1124 Q_PROPERTY (bool enableLauncherWhileLocked
1125 READ enableLauncherWhileLocked
1126 NOTIFY enableLauncherWhileLockedChanged)
1127@@ -66,6 +70,8 @@
1128 Q_PROPERTY(bool hereLicensePathValid // qml sees a null string as "", so we use proxy setting for that
1129 READ hereLicensePathValid
1130 NOTIFY hereLicensePathChanged)
1131+ Q_PROPERTY(QString realName READ realName WRITE setRealName NOTIFY realNameChanged)
1132+ Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY emailChanged)
1133
1134 public:
1135 enum PasswordDisplayHint {
1136@@ -80,6 +86,8 @@
1137 void setUser(const QString &user);
1138 bool demoEdges() const;
1139 void setDemoEdges(bool demoEdges);
1140+ QStringList demoEdgesCompleted() const;
1141+ Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
1142 bool enableLauncherWhileLocked() const;
1143 bool enableIndicatorsWhileLocked() const;
1144 QString backgroundFile() const;
1145@@ -91,10 +99,15 @@
1146 void setHereEnabled(bool enabled);
1147 QString hereLicensePath() const;
1148 bool hereLicensePathValid() const;
1149+ QString realName() const;
1150+ void setRealName(const QString &realName);
1151+ QString email() const;
1152+ void setEmail(const QString &email);
1153
1154 Q_SIGNALS:
1155 void userChanged();
1156 void demoEdgesChanged();
1157+ void demoEdgesCompletedChanged();
1158 void enableLauncherWhileLockedChanged();
1159 void enableIndicatorsWhileLockedChanged();
1160 void backgroundFileChanged();
1161@@ -103,36 +116,41 @@
1162 void failedLoginsChanged();
1163 void hereEnabledChanged();
1164 void hereLicensePathChanged();
1165+ void realNameChanged();
1166+ void emailChanged();
1167
1168 private Q_SLOTS:
1169 void onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed);
1170 void onMaybeChanged(const QString &user);
1171
1172 private:
1173- void updateDemoEdges(bool async = true);
1174- void updateEnableLauncherWhileLocked(bool async = true);
1175- void updateEnableIndicatorsWhileLocked(bool async = true);
1176- void updateBackgroundFile(bool async = true);
1177- void updateMouseCursorSpeed();
1178- void updateTouchpadCursorSpeed();
1179- void updateStatsWelcomeScreen(bool async = true);
1180- void updatePasswordDisplayHint(bool async = true);
1181- void updateFailedLogins(bool async = true);
1182- void updateHereEnabled(bool async = true);
1183- void updateHereLicensePath(bool async = true);
1184-
1185+ typedef QVariant (*ProxyConverter)(const QVariant &);
1186+
1187+ void refresh(bool async);
1188+ void registerProperty(const QString &interface, const QString &property, const QString &signal);
1189+ void registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter = nullptr);
1190+
1191+ void updateAllProperties(const QString &interface, bool async);
1192+ void updateProperty(const QString &interface, const QString &property);
1193+ void updateCache(const QString &interface, const QString &property, const QVariant &value);
1194+
1195+ void setProperty(const QString &interface, const QString &property, const QVariant &value);
1196+ QVariant getProperty(const QString &interface, const QString &property) const;
1197+
1198+ void emitChangedForProperty(const QString &interface, const QString &property);
1199+
1200+ struct PropertyInfo {
1201+ QVariant value{};
1202+ QString signal{};
1203+ QDBusInterface *proxyInterface{};
1204+ QString proxyMethod{};
1205+ ProxyConverter proxyConverter{};
1206+ };
1207+ typedef QHash< QString, QHash<QString, PropertyInfo> > PropertyHash;
1208+ PropertyHash m_properties;
1209 AccountsServiceDBusAdaptor *m_service;
1210 QDBusInterface *m_unityInput;
1211 QString m_user;
1212- bool m_demoEdges;
1213- bool m_enableLauncherWhileLocked;
1214- bool m_enableIndicatorsWhileLocked;
1215- QString m_backgroundFile;
1216- bool m_statsWelcomeScreen;
1217- PasswordDisplayHint m_passwordDisplayHint;
1218- uint m_failedLogins;
1219- bool m_hereEnabled;
1220- QString m_hereLicensePath;
1221 };
1222
1223 #endif
1224
1225=== modified file 'plugins/AccountsService/AccountsService.qmltypes'
1226--- plugins/AccountsService/AccountsService.qmltypes 2015-02-13 09:01:16 +0000
1227+++ plugins/AccountsService/AccountsService.qmltypes 2016-03-11 18:12:46 +0000
1228@@ -23,6 +23,7 @@
1229 }
1230 Property { name: "user"; type: "string" }
1231 Property { name: "demoEdges"; type: "bool" }
1232+ Property { name: "demoEdgesCompleted"; type: "QStringList"; isReadonly: true }
1233 Property { name: "enableLauncherWhileLocked"; type: "bool"; isReadonly: true }
1234 Property { name: "enableIndicatorsWhileLocked"; type: "bool"; isReadonly: true }
1235 Property { name: "backgroundFile"; type: "string"; isReadonly: true }
1236@@ -32,5 +33,9 @@
1237 Property { name: "hereEnabled"; type: "bool" }
1238 Property { name: "hereLicensePath"; type: "string"; isReadonly: true }
1239 Property { name: "hereLicensePathValid"; type: "bool"; isReadonly: true }
1240+ Method {
1241+ name: "markDemoEdgeCompleted"
1242+ Parameter { name: "edge"; type: "string" }
1243+ }
1244 }
1245 }
1246
1247=== modified file 'plugins/AccountsService/AccountsServiceDBusAdaptor.cpp'
1248--- plugins/AccountsService/AccountsServiceDBusAdaptor.cpp 2015-10-26 14:05:14 +0000
1249+++ plugins/AccountsService/AccountsServiceDBusAdaptor.cpp 2016-03-11 18:12:46 +0000
1250@@ -1,5 +1,5 @@
1251 /*
1252- * Copyright (C) 2013 Canonical, Ltd.
1253+ * Copyright (C) 2013-2016 Canonical, Ltd.
1254 *
1255 * This program is free software; you can redistribute it and/or modify
1256 * it under the terms of the GNU General Public License as published by
1257@@ -12,8 +12,6 @@
1258 *
1259 * You should have received a copy of the GNU General Public License
1260 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1261- *
1262- * Author: Michael Terry <michael.terry@canonical.com>
1263 */
1264
1265 #include "AccountsServiceDBusAdaptor.h"
1266@@ -37,6 +35,15 @@
1267 connection, this);
1268 }
1269
1270+QDBusPendingReply<QVariantMap> AccountsServiceDBusAdaptor::getAllPropertiesAsync(const QString &user, const QString &interface)
1271+{
1272+ QDBusInterface *iface = getUserInterface(user);
1273+ if (iface != nullptr && iface->isValid()) {
1274+ return iface->asyncCall(QStringLiteral("GetAll"), interface);
1275+ }
1276+ return QDBusPendingReply<QVariantMap>(QDBusMessage::createError(QDBusError::Other, QStringLiteral("Invalid Interface")));
1277+}
1278+
1279 QDBusPendingReply<QVariant> AccountsServiceDBusAdaptor::getUserPropertyAsync(const QString &user, const QString &interface, const QString &property)
1280 {
1281 QDBusInterface *iface = getUserInterface(user);
1282@@ -80,7 +87,7 @@
1283 m_ignoreNextChanged = false;
1284 }
1285
1286-QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path)
1287+QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path) const
1288 {
1289 QMap<QString, QDBusInterface *>::const_iterator i;
1290 for (i = m_users.constBegin(); i != m_users.constEnd(); ++i) {
1291
1292=== modified file 'plugins/AccountsService/AccountsServiceDBusAdaptor.h'
1293--- plugins/AccountsService/AccountsServiceDBusAdaptor.h 2015-10-26 14:05:14 +0000
1294+++ plugins/AccountsService/AccountsServiceDBusAdaptor.h 2016-03-11 18:12:46 +0000
1295@@ -1,5 +1,5 @@
1296 /*
1297- * Copyright (C) 2013 Canonical, Ltd.
1298+ * Copyright (C) 2013-2016 Canonical, Ltd.
1299 *
1300 * This program is free software; you can redistribute it and/or modify
1301 * it under the terms of the GNU General Public License as published by
1302@@ -12,8 +12,6 @@
1303 *
1304 * You should have received a copy of the GNU General Public License
1305 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1306- *
1307- * Authors: Michael Terry <michael.terry@canonical.com>
1308 */
1309
1310 #ifndef UNITY_ACCOUNTSSERVICEDBUSADAPTOR_H
1311@@ -35,8 +33,9 @@
1312 explicit AccountsServiceDBusAdaptor(QObject *parent = 0);
1313 ~AccountsServiceDBusAdaptor() = default;
1314
1315- Q_INVOKABLE QDBusPendingReply<QVariant> getUserPropertyAsync(const QString &user, const QString &interface, const QString &property);
1316- Q_INVOKABLE QDBusPendingCall setUserPropertyAsync(const QString &user, const QString &interface, const QString &property, const QVariant &value);
1317+ QDBusPendingReply<QVariantMap> getAllPropertiesAsync(const QString &user, const QString &interface);
1318+ QDBusPendingReply<QVariant> getUserPropertyAsync(const QString &user, const QString &interface, const QString &property);
1319+ QDBusPendingCall setUserPropertyAsync(const QString &user, const QString &interface, const QString &property, const QVariant &value);
1320
1321 Q_SIGNALS:
1322 void propertiesChanged(const QString &user, const QString &interface, const QStringList &changed);
1323@@ -48,7 +47,7 @@
1324
1325 private:
1326 QDBusInterface *getUserInterface(const QString &user);
1327- QString getUserForPath(const QString &path);
1328+ QString getUserForPath(const QString &path) const;
1329
1330 QDBusInterface *m_accountsManager;
1331 QMap<QString, QDBusInterface *> m_users;
1332
1333=== modified file 'plugins/AccountsService/com.canonical.unity.AccountsService.xml'
1334--- plugins/AccountsService/com.canonical.unity.AccountsService.xml 2015-02-04 15:12:36 +0000
1335+++ plugins/AccountsService/com.canonical.unity.AccountsService.xml 2016-03-11 18:12:46 +0000
1336@@ -14,6 +14,11 @@
1337 <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
1338 </property>
1339
1340+ <!-- List of tutorial pages that have been completed by the user -->
1341+ <property name="DemoEdgesCompleted" type="as" access="readwrite">
1342+ <annotation name="org.freedesktop.Accounts.DefaultValue" value="[]"/>
1343+ </property>
1344+
1345 <property name="LauncherItems" type="aa{sv}" access="readwrite">
1346 <annotation name="org.freedesktop.Accounts.DefaultValue" value="[{'defaults': <true>}]"/>
1347 </property>
1348
1349=== modified file 'plugins/Dash/AudioProgressBar.qml'
1350--- plugins/Dash/AudioProgressBar.qml 2015-12-03 14:44:08 +0000
1351+++ plugins/Dash/AudioProgressBar.qml 2016-03-11 18:12:46 +0000
1352@@ -31,6 +31,7 @@
1353 anchors { left: parent.left; right: parent.right }
1354 height: units.dp(6)
1355 source: "graphics/music_progress_bg.png"
1356+ asynchronous: true
1357 sourceSize.width: width
1358 sourceSize.height: height
1359 }
1360
1361=== modified file 'plugins/Dash/CardCreator.js'
1362--- plugins/Dash/CardCreator.js 2016-02-12 00:11:52 +0000
1363+++ plugins/Dash/CardCreator.js 2016-03-11 18:12:46 +0000
1364@@ -18,12 +18,13 @@
1365
1366 // %1 is the template["card-background"]["elements"][0]
1367 // %2 is the template["card-background"]["elements"][1]
1368-// %3 is the template["card-background"] string
1369+// %3 is whether the loader should be asynchronous or not
1370+// %4 is the template["card-background"] string
1371 var kBackgroundLoaderCode = 'Loader {\n\
1372 id: backgroundLoader; \n\
1373 objectName: "backgroundLoader"; \n\
1374 anchors.fill: parent; \n\
1375- asynchronous: root.asynchronous; \n\
1376+ asynchronous: %3; \n\
1377 visible: status == Loader.Ready; \n\
1378 sourceComponent: UbuntuShape { \n\
1379 objectName: "background"; \n\
1380@@ -46,7 +47,7 @@
1381 objectName: "backgroundImage"; \n\
1382 source: { \n\
1383 if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
1384- else return %3; \n\
1385+ else return %4; \n\
1386 } \n\
1387 } \n\
1388 function getColor(index) { \n\
1389@@ -63,8 +64,9 @@
1390 // %3 is used as image height
1391 // %4 is used for artShapeSource.hideSource and inner Loader visible
1392 // %5 is used as aspect ratio fallback
1393-// %6 is injected as code to artImage
1394-// %7 is used as image fallback
1395+// %6 is whether the loader should be asynchronous or not
1396+// %7 is injected as code to artImage
1397+// %8 is used as image fallback
1398 var kArtShapeHolderCode = 'Item { \n\
1399 id: artShapeHolder; \n\
1400 height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
1401@@ -73,9 +75,9 @@
1402 Loader { \n\
1403 id: artShapeLoader; \n\
1404 objectName: "artShapeLoader"; \n\
1405- readonly property string cardArt: cardData && cardData["art"] || %7; \n\
1406+ readonly property string cardArt: cardData && cardData["art"] || %8; \n\
1407 active: cardArt != ""; \n\
1408- asynchronous: root.asynchronous; \n\
1409+ asynchronous: %6; \n\
1410 visible: status == Loader.Ready; \n\
1411 sourceComponent: Item { \n\
1412 id: artShape; \n\
1413@@ -132,10 +134,10 @@
1414 id: artImage; \n\
1415 objectName: "artImage"; \n\
1416 source: artShapeLoader.cardArt; \n\
1417- asynchronous: root.asynchronous; \n\
1418+ asynchronous: %6; \n\
1419 width: %2; \n\
1420 height: %3; \n\
1421- %6 \n\
1422+ %7 \n\
1423 } \n\
1424 } \n\
1425 } \n\
1426@@ -144,6 +146,7 @@
1427 // %1 is anchors.fill
1428 // %2 is width
1429 // %3 is height
1430+// %4 is whether the icon should be asynchronous or not
1431 var kAudioButtonCode = 'AbstractButton { \n\
1432 id: audioButton; \n\
1433 anchors.fill: %1; \n\
1434@@ -169,6 +172,7 @@
1435 opacity: 0.9; \n\
1436 name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start"; \n\
1437 color: "white"; \n\
1438+ asynchronous: %4; \n\
1439 } \n\
1440 onClicked: { \n\
1441 if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) { \n\
1442@@ -187,12 +191,14 @@
1443 } \n\
1444 }';
1445
1446+// %1 is whether the loader should be asynchronous or not
1447+// %2 is the header height code
1448 var kOverlayLoaderCode = 'Loader { \n\
1449 id: overlayLoader; \n\
1450- readonly property real overlayHeight: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
1451+ readonly property real overlayHeight: %2 + units.gu(2); \n\
1452 anchors.fill: artShapeHolder; \n\
1453 active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \n\
1454- asynchronous: root.asynchronous; \n\
1455+ asynchronous: %1; \n\
1456 visible: showHeader && status == Loader.Ready; \n\
1457 sourceComponent: UbuntuShapeOverlay { \n\
1458 id: overlay; \n\
1459@@ -211,17 +217,19 @@
1460 objectName: "outerRow"; \n\
1461 property real margins: units.gu(1); \n\
1462 spacing: margins; \n\
1463- height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\
1464+ %2\
1465 anchors { %1 } \n\
1466 anchors.right: parent.right; \n\
1467 anchors.margins: margins; \n\
1468 anchors.rightMargin: 0; \n\
1469 data: [ \n\
1470- %2 \n\
1471+ %3 \n\
1472 ] \n\
1473 }\n';
1474 var args = Array.prototype.slice.call(arguments);
1475- var code = kHeaderRowCodeTemplate.arg(args.shift()).arg(args.join(',\n'));
1476+ var isCardTool = args.shift();
1477+ var heightCode = isCardTool ? "" : "height: root.fixedHeaderHeight; \n";
1478+ var code = kHeaderRowCodeTemplate.arg(args.shift()).arg(heightCode).arg(args.join(',\n'));
1479 return code;
1480 }
1481
1482@@ -242,10 +250,11 @@
1483 }
1484
1485 // %1 is used as anchors of mascotShapeLoader
1486+// %2 is whether the loader should be asynchronous or not
1487 var kMascotShapeLoaderCode = 'Loader { \n\
1488 id: mascotShapeLoader; \n\
1489 objectName: "mascotShapeLoader"; \n\
1490- asynchronous: root.asynchronous; \n\
1491+ asynchronous: %2; \n\
1492 active: mascotImage.status === Image.Ready; \n\
1493 visible: showHeader && active && status == Loader.Ready; \n\
1494 width: units.gu(6); \n\
1495@@ -275,6 +284,7 @@
1496 // %2 is used as color of titleLabel
1497 // %3 is used as extra condition for visible of titleLabel
1498 // %4 is used as title width
1499+// %5 is used as horizontal alignment
1500 var kTitleLabelCode = 'Label { \n\
1501 id: titleLabel; \n\
1502 objectName: "titleLabel"; \n\
1503@@ -289,7 +299,7 @@
1504 width: %4; \n\
1505 text: root.title; \n\
1506 font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal; \n\
1507- horizontalAlignment: root.titleAlignment; \n\
1508+ horizontalAlignment: %5; \n\
1509 }\n';
1510
1511 // %1 is used as extra anchors of emblemIcon
1512@@ -398,7 +408,7 @@
1513 return colorString;
1514 }
1515
1516-function cardString(template, components) {
1517+function cardString(template, components, isCardTool) {
1518 var code;
1519
1520 var templateInteractive = (template == null ? true : (template["non-interactive"] !== undefined ? !template["non-interactive"] : true)) ? "true" : "false";
1521@@ -410,16 +420,16 @@
1522 property string backgroundShapeStyle: "inset"; \n\
1523 property real fontScale: 1.0; \n\
1524 property var scopeStyle: null; \n\
1525- property int titleAlignment: Text.AlignLeft; \n\
1526- property int fixedHeaderHeight: -1; \n\
1527+ %2\
1528 property size fixedArtShapeSize: Qt.size(-1, -1); \n\
1529 readonly property string title: cardData && cardData["title"] || ""; \n\
1530- property bool asynchronous: true; \n\
1531 property bool showHeader: true; \n\
1532 implicitWidth: childrenRect.width; \n\
1533 enabled: %1; \n\
1534 \n'.arg(templateInteractive);
1535
1536+ code = code.arg(isCardTool ? "" : "property int fixedHeaderHeight: -1; \n");
1537+
1538 var hasArt = components["art"] && components["art"]["field"] || false;
1539 var hasSummary = components["summary"] || false;
1540 var isConciergeMode = components["art"] && components["art"]["conciergeMode"] || false;
1541@@ -435,6 +445,7 @@
1542 var hasHeaderRow = hasMascot && hasTitle;
1543 var hasAttributes = hasTitle && components["attributes"] && components["attributes"]["field"] || false;
1544 var isAudio = template["quick-preview-type"] === "audio";
1545+ var asynchronous = isCardTool ? "false" : "true";
1546
1547 if (isAudio) {
1548 // For now we only support audio cards with [optional] art, title, subtitle
1549@@ -468,7 +479,7 @@
1550 backgroundElements1 = '"%1"'.arg(element1);
1551 }
1552 }
1553- code += kBackgroundLoaderCode.arg(backgroundElements0).arg(backgroundElements1).arg(templateCardBackground);
1554+ code += kBackgroundLoaderCode.arg(backgroundElements0).arg(backgroundElements1).arg(asynchronous).arg(templateCardBackground);
1555 }
1556
1557 if (hasArt) {
1558@@ -497,23 +508,31 @@
1559 if (isNaN(aspectRatio)) {
1560 aspectRatio = 1;
1561 }
1562- var fallback = components["art"] && components["art"]["fallback"] || "";
1563+ var fallback = !isCardTool && components["art"] && components["art"]["fallback"] || "";
1564 fallback = encodeURI(fallback);
1565 var fallbackStatusCode = "";
1566 var fallbackURICode = '""';
1567 if (fallback !== "") {
1568 // fallbackStatusCode has %6 in it because we want to substitute it for fallbackURICode
1569- // which in kArtShapeHolderCode is %7
1570- fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %7;';
1571+ // which in kArtShapeHolderCode is %8
1572+ fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %8;';
1573 fallbackURICode = 'decodeURI("%1")'.arg(fallback);
1574 }
1575- code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode).arg(isConciergeMode ? "false" : "true").arg(aspectRatio).arg(fallbackStatusCode).arg(fallbackURICode);
1576+ code += kArtShapeHolderCode.arg(artAnchors)
1577+ .arg(widthCode)
1578+ .arg(heightCode)
1579+ .arg(isConciergeMode ? "false" : "true")
1580+ .arg(aspectRatio)
1581+ .arg(asynchronous)
1582+ .arg(fallbackStatusCode)
1583+ .arg(fallbackURICode);
1584 } else {
1585 code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
1586 }
1587
1588 if (headerAsOverlay) {
1589- code += kOverlayLoaderCode;
1590+ var headerHeightCode = isCardTool ? "headerHeight" : "root.fixedHeaderHeight";
1591+ code += kOverlayLoaderCode.arg(asynchronous).arg(headerHeightCode);
1592 }
1593
1594 var headerVerticalAnchors;
1595@@ -595,11 +614,11 @@
1596 }
1597
1598 if (useMascotShape) {
1599- mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors);
1600+ mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors).arg(asynchronous);
1601 }
1602
1603 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
1604- var fallback = components["mascot"] && components["mascot"]["fallback"] || "";
1605+ var fallback = !isCardTool && components["mascot"] && components["mascot"]["fallback"] || "";
1606 fallback = encodeURI(fallback);
1607 var fallbackStatusCode = "";
1608 var fallbackURICode = '""';
1609@@ -715,9 +734,24 @@
1610 }
1611 }
1612
1613+ var titleAlignment = "Text.AlignHCenter";
1614+ if (template["card-layout"] === "horizontal"
1615+ || typeof components["title"] !== "object"
1616+ || components["title"]["align"] === "left") titleAlignment = "Text.AlignLeft";
1617+ var keys = ["mascot", "emblem", "subtitle", "attributes", "summary"];
1618+ for (var key in keys) {
1619+ key = keys[key];
1620+ try {
1621+ if (typeof components[key] === "string"
1622+ || typeof components[key]["field"] === "string") titleAlignment = "Text.AlignLeft";
1623+ } catch (e) {
1624+ continue;
1625+ }
1626+ }
1627+
1628 // code for different elements
1629 var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': '');
1630- var titleCode = kTitleLabelCode.arg(titleAnchors).arg(titleColor).arg(titleLabelVisibleExtra).arg(titleWidth);
1631+ var titleCode = kTitleLabelCode.arg(titleAnchors).arg(titleColor).arg(titleLabelVisibleExtra).arg(titleWidth).arg(titleAlignment);
1632 var subtitleCode;
1633 var attributesCode;
1634
1635@@ -759,7 +793,7 @@
1636 if (mascotShapeCode != '') {
1637 rowCode.unshift(mascotShapeCode);
1638 }
1639- code += kHeaderRowCodeGenerator(headerVerticalAnchors + headerLeftAnchor, rowCode)
1640+ code += kHeaderRowCodeGenerator(isCardTool, headerVerticalAnchors + headerLeftAnchor, rowCode)
1641 } else {
1642 code += mascotShapeCode + mascotCode + titleSubtitleCode;
1643 }
1644@@ -783,9 +817,10 @@
1645 } else {
1646 audioButtonAnchorsFill = 'undefined';
1647 audioButtonWidth = 'height';
1648- audioButtonHeight = '(root.fixedHeaderHeight > 0 ? root.fixedHeaderHeight : headerHeight) + 2 * units.gu(1)';
1649+ audioButtonHeight = isCardTool ? 'headerHeight + 2 * units.gu(1)'
1650+ : 'root.fixedHeaderHeight + 2 * units.gu(1)';
1651 }
1652- code += kAudioButtonCode.arg(audioButtonAnchorsFill).arg(audioButtonWidth).arg(audioButtonHeight);
1653+ code += kAudioButtonCode.arg(audioButtonAnchorsFill).arg(audioButtonWidth).arg(audioButtonHeight).arg(asynchronous);
1654 }
1655
1656 if (hasSummary) {
1657@@ -854,13 +889,13 @@
1658 return code;
1659 }
1660
1661-function createCardComponent(parent, template, components, identifier) {
1662+function createCardComponent(parent, template, components, isCardTool, identifier) {
1663 var imports = 'import QtQuick 2.4; \n\
1664 import Ubuntu.Components 1.3; \n\
1665 import Ubuntu.Settings.Components 0.1; \n\
1666 import Dash 0.1;\n\
1667 import Utils 0.1;\n';
1668- var card = cardString(template, components);
1669+ var card = cardString(template, components, isCardTool);
1670 var code = imports + 'Component {\n' + card + '}\n';
1671
1672 try {
1673
1674=== modified file 'plugins/Dash/CardCreatorCache.qml'
1675--- plugins/Dash/CardCreatorCache.qml 2016-01-21 17:56:08 +0000
1676+++ plugins/Dash/CardCreatorCache.qml 2016-03-11 18:12:46 +0000
1677@@ -23,16 +23,16 @@
1678
1679 property var cache: new Object();
1680
1681- function getCardComponent(template, components) {
1682+ function getCardComponent(template, components, isCardTool) {
1683 if (template === undefined || components === undefined)
1684 return undefined;
1685
1686 var tString = JSON.stringify(template);
1687 var cString = JSON.stringify(components);
1688- var allString = tString + cString;
1689+ var allString = tString + cString + isCardTool;
1690 var component = cache[allString];
1691 if (component === undefined) {
1692- component = CardCreator.createCardComponent(root, template, components, allString);
1693+ component = CardCreator.createCardComponent(root, template, components, isCardTool, allString);
1694 cache[allString] = component;
1695 }
1696 return component;
1697
1698=== modified file 'plugins/Dash/plugin.cpp'
1699--- plugins/Dash/plugin.cpp 2015-09-18 07:44:50 +0000
1700+++ plugins/Dash/plugin.cpp 2016-03-11 18:12:46 +0000
1701@@ -28,12 +28,12 @@
1702 static QUrl oauthCleanedUrl(QUrl u)
1703 {
1704 QUrlQuery q(u);
1705- q.removeQueryItem("oauth_nonce");
1706- q.removeQueryItem("oauth_timestamp");
1707- q.removeQueryItem("oauth_consumer_key");
1708- q.removeQueryItem("oauth_signature_method");
1709- q.removeQueryItem("oauth_version");
1710- q.removeQueryItem("oauth_signature");
1711+ q.removeQueryItem(QStringLiteral("oauth_nonce"));
1712+ q.removeQueryItem(QStringLiteral("oauth_timestamp"));
1713+ q.removeQueryItem(QStringLiteral("oauth_consumer_key"));
1714+ q.removeQueryItem(QStringLiteral("oauth_signature_method"));
1715+ q.removeQueryItem(QStringLiteral("oauth_version"));
1716+ q.removeQueryItem(QStringLiteral("oauth_signature"));
1717 u.setQuery(q);
1718 return u;
1719 }
1720
1721=== modified file 'plugins/GlobalShortcut/globalshortcutregistry.cpp'
1722--- plugins/GlobalShortcut/globalshortcutregistry.cpp 2015-11-20 15:01:39 +0000
1723+++ plugins/GlobalShortcut/globalshortcutregistry.cpp 2016-03-11 18:12:46 +0000
1724@@ -35,13 +35,13 @@
1725
1726 bool GlobalShortcutRegistry::hasShortcut(const QVariant &seq) const
1727 {
1728- return m_shortcuts.keys().contains(seq);
1729+ return m_shortcuts.contains(seq);
1730 }
1731
1732 void GlobalShortcutRegistry::addShortcut(const QVariant &seq, GlobalShortcut *sc)
1733 {
1734 if (sc) {
1735- if (!m_shortcuts.keys().contains(seq)) { // create a new entry
1736+ if (!m_shortcuts.contains(seq)) { // create a new entry
1737 m_shortcuts.insert(seq, {sc});
1738 } else { // append to an existing one
1739 auto shortcuts = m_shortcuts[seq];
1740@@ -75,8 +75,8 @@
1741
1742 if (event->type() == QEvent::KeyPress) {
1743 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
1744- QKeySequence seq = QKeySequence(keyEvent->key() + keyEvent->modifiers());
1745- if (m_shortcuts.keys().contains(seq)) {
1746+ int seq = keyEvent->key() + keyEvent->modifiers();
1747+ if (m_shortcuts.contains(seq)) {
1748 const auto shortcuts = m_shortcuts.value(seq);
1749 Q_FOREACH(const auto &shortcut, shortcuts) {
1750 if (shortcut) {
1751
1752=== modified file 'plugins/IntegratedLightDM/liblightdm/CMakeLists.txt'
1753--- plugins/IntegratedLightDM/liblightdm/CMakeLists.txt 2016-02-01 15:15:09 +0000
1754+++ plugins/IntegratedLightDM/liblightdm/CMakeLists.txt 2016-03-11 18:12:46 +0000
1755@@ -5,13 +5,16 @@
1756 UsersModel.cpp
1757 GreeterPrivate.cpp
1758 UsersModelPrivate.cpp
1759+ ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
1760 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
1761 )
1762
1763 add_library(integratedLightDM STATIC ${LibLightDM_SOURCES})
1764+add_library(integratedLightDMSession STATIC ${LibLightDM_SOURCES})
1765 add_library(MockLightDM-demo-shared SHARED ${LibLightDM_SOURCES})
1766
1767 include_directories(
1768+ ${CMAKE_SOURCE_DIR}/plugins/AccountsService
1769 ${CMAKE_CURRENT_BINARY_DIR}
1770 ${GLIB_INCLUDE_DIRS}
1771 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
1772@@ -22,17 +25,27 @@
1773 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
1774 -lpam
1775 )
1776+target_link_libraries(integratedLightDMSession
1777+ ${GLIB_LIBRARIES}
1778+ ${LIBUSERMETRICSOUTPUT_LDFLAGS}
1779+ -lpam
1780+)
1781 target_link_libraries(MockLightDM-demo-shared
1782 ${GLIB_LIBRARIES}
1783 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
1784 -lpam
1785 )
1786
1787-qt5_use_modules(integratedLightDM Concurrent Gui)
1788-qt5_use_modules(MockLightDM-demo-shared Concurrent Gui)
1789+qt5_use_modules(integratedLightDM Concurrent DBus Gui)
1790+qt5_use_modules(integratedLightDMSession Concurrent DBus Gui)
1791+qt5_use_modules(MockLightDM-demo-shared Concurrent DBus Gui)
1792
1793-set_target_properties(integratedLightDM PROPERTIES COMPILE_FLAGS -fPIC)
1794+set_target_properties(integratedLightDM PROPERTIES
1795+ COMPILE_FLAGS "-DSM_BUSNAME=systemBus -fPIC")
1796+set_target_properties(integratedLightDMSession PROPERTIES
1797+ COMPILE_FLAGS "-DSM_BUSNAME=sessionBus -fPIC")
1798 set_target_properties(MockLightDM-demo-shared PROPERTIES
1799+ COMPILE_FLAGS "-DSM_BUSNAME=systemBus"
1800 OUTPUT_NAME lightdm-qt5-2)
1801
1802 install(TARGETS MockLightDM-demo-shared
1803
1804=== modified file 'plugins/IntegratedLightDM/liblightdm/UsersModel.cpp'
1805--- plugins/IntegratedLightDM/liblightdm/UsersModel.cpp 2015-09-14 09:11:08 +0000
1806+++ plugins/IntegratedLightDM/liblightdm/UsersModel.cpp 2016-03-11 18:12:46 +0000
1807@@ -54,24 +54,10 @@
1808 roles[ImagePathRole] = "imagePath";
1809 setRoleNames(roles);
1810
1811- // Now modify our mock user backgrounds
1812- QDir bgdir = QDir(QStringLiteral("/usr/share/demo-assets/shell/backgrounds/"));
1813- QStringList backgrounds = bgdir.entryList(QDir::Files | QDir::NoDotAndDotDot);
1814-
1815- for (int i = 0, j = 0; i < d->entries.size(); i++) {
1816- Entry &entry = d->entries[i];
1817- if (entry.background.isNull() && !backgrounds.isEmpty()) {
1818- entry.background = bgdir.filePath(backgrounds[j++]);
1819- if (j >= backgrounds.length()) {
1820- j = 0;
1821- }
1822- }
1823- }
1824-}
1825-
1826-UsersModel::~UsersModel()
1827-{
1828- delete d_ptr;
1829+ connect(d_ptr, &UsersModelPrivate::dataChanged, this, [this](int i) {
1830+ QModelIndex index = createIndex(i, 0);
1831+ Q_EMIT dataChanged(index, index);
1832+ });
1833 }
1834
1835 int UsersModel::rowCount(const QModelIndex &parent) const
1836
1837=== modified file 'plugins/IntegratedLightDM/liblightdm/UsersModel.h'
1838--- plugins/IntegratedLightDM/liblightdm/UsersModel.h 2015-04-30 09:31:51 +0000
1839+++ plugins/IntegratedLightDM/liblightdm/UsersModel.h 2016-03-11 18:12:46 +0000
1840@@ -41,7 +41,7 @@
1841
1842 public:
1843 explicit UsersModel(QObject *parent = 0);
1844- virtual ~UsersModel();
1845+ virtual ~UsersModel() = default;
1846
1847 enum UserModelRoles {NameRole = Qt::UserRole,
1848 RealNameRole,
1849
1850=== modified file 'plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp'
1851--- plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp 2016-02-04 14:10:42 +0000
1852+++ plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp 2016-03-11 18:12:46 +0000
1853@@ -18,7 +18,11 @@
1854
1855 #include "UsersModelPrivate.h"
1856
1857+#include "AccountsServiceDBusAdaptor.h"
1858+#include "UsersModel.h"
1859+
1860 #include <glib.h>
1861+#include <QDebug>
1862 #include <QDir>
1863 #include <QSettings>
1864 #include <QStringList>
1865@@ -27,7 +31,9 @@
1866 {
1867
1868 UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
1869- : q_ptr(parent)
1870+ : QObject(parent),
1871+ q_ptr(parent),
1872+ m_service(new AccountsServiceDBusAdaptor(this))
1873 {
1874 QFileInfo demoFile(QDir::homePath() + "/.unity8-greeter-demo");
1875 QString currentUser = g_get_user_name();
1876@@ -43,15 +49,43 @@
1877 entries.append({user, name, 0, 0, false, false, 0, 0});
1878 }
1879 } else {
1880- // If we were using the actual liblightdm, we could just ask it
1881- // for the user's real name. But we aren't. We *should* ask
1882- // AccountsService for the real name, like liblightdm does internally,
1883- // but this is close enough since AS and passwd are always in sync.
1884- QString realName = QString::fromUtf8(g_get_real_name()); // gets name from passwd entry
1885- if (realName == QStringLiteral("Unknown")) { // glib doesn't translate this string
1886- realName.clear();
1887- }
1888- entries.append({currentUser, realName, 0, 0, false, false, 0, 0});
1889+ entries.append({currentUser, 0, 0, 0, false, false, 0, 0});
1890+
1891+ connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged,
1892+ this, [this](const QString &user) {
1893+ if (user == entries[0].username) {
1894+ updateName(true);
1895+ }
1896+ });
1897+ updateName(false);
1898+ }
1899+}
1900+
1901+void UsersModelPrivate::updateName(bool async)
1902+{
1903+ auto pendingReply = m_service->getUserPropertyAsync(entries[0].username,
1904+ QStringLiteral("org.freedesktop.Accounts.User"),
1905+ QStringLiteral("RealName"));
1906+ auto *watcher = new QDBusPendingCallWatcher(pendingReply, this);
1907+
1908+ connect(watcher, &QDBusPendingCallWatcher::finished,
1909+ this, [this](QDBusPendingCallWatcher* watcher) {
1910+
1911+ QDBusPendingReply<QVariant> reply = *watcher;
1912+ watcher->deleteLater();
1913+ if (reply.isError()) {
1914+ qWarning() << "Failed to get 'RealName' property - " << reply.error().message();
1915+ return;
1916+ }
1917+
1918+ const QString realName = reply.value().toString();
1919+ if (entries[0].real_name != realName) {
1920+ entries[0].real_name = realName;
1921+ Q_EMIT dataChanged(0);
1922+ }
1923+ });
1924+ if (!async) {
1925+ watcher->waitForFinished();
1926 }
1927 }
1928
1929
1930=== modified file 'plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h'
1931--- plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h 2015-01-20 11:50:19 +0000
1932+++ plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h 2016-03-11 18:12:46 +0000
1933@@ -19,8 +19,11 @@
1934 #ifndef UNITY_MOCK_USERSMODEL_PRIVATE_H
1935 #define UNITY_MOCK_USERSMODEL_PRIVATE_H
1936
1937-#include <QtCore/QList>
1938-#include <QtCore/QString>
1939+#include <QList>
1940+#include <QObject>
1941+#include <QString>
1942+
1943+class AccountsServiceDBusAdaptor;
1944
1945 namespace QLightDM
1946 {
1947@@ -39,19 +42,28 @@
1948 QString infographic;
1949 };
1950
1951-class UsersModelPrivate
1952+class UsersModelPrivate : public QObject
1953 {
1954+ Q_OBJECT
1955+
1956 public:
1957 explicit UsersModelPrivate(UsersModel *parent = 0);
1958 virtual ~UsersModelPrivate() = default;
1959
1960 QList<Entry> entries;
1961
1962+Q_SIGNALS:
1963+ void dataChanged(int);
1964+
1965 protected:
1966 UsersModel * const q_ptr;
1967
1968 private:
1969 Q_DECLARE_PUBLIC(UsersModel)
1970+
1971+ void updateName(bool async);
1972+
1973+ AccountsServiceDBusAdaptor *m_service;
1974 };
1975
1976 }
1977
1978=== modified file 'plugins/ScreenGrabber/screengrabber.cpp'
1979--- plugins/ScreenGrabber/screengrabber.cpp 2015-11-18 18:38:36 +0000
1980+++ plugins/ScreenGrabber/screengrabber.cpp 2016-03-11 18:12:46 +0000
1981@@ -46,12 +46,10 @@
1982
1983 QDir screenshotsDir;
1984 if (qEnvironmentVariableIsSet("UNITY_TESTING")) {
1985- qDebug() << "Using test environment";
1986 QTemporaryDir tDir;
1987 tDir.setAutoRemove(false);
1988 screenshotsDir = tDir.path();
1989 } else {
1990- qDebug() << "Using real environment";
1991 screenshotsDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
1992 }
1993 screenshotsDir.mkpath(QStringLiteral("Screenshots"));
1994
1995=== modified file 'plugins/Ubuntu/Gestures/DirectionalDragArea.cpp'
1996--- plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 2015-12-16 18:28:21 +0000
1997+++ plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 2016-03-11 18:12:46 +0000
1998@@ -194,6 +194,26 @@
1999 }
2000 }
2001
2002+bool DirectionalDragArea::monitorOnly() const
2003+{
2004+ return d->monitorOnly;
2005+}
2006+
2007+void DirectionalDragArea::setMonitorOnly(bool monitorOnly)
2008+{
2009+ if (d->monitorOnly != monitorOnly) {
2010+ d->monitorOnly = monitorOnly;
2011+
2012+ if (monitorOnly && d->status == DirectionalDragAreaPrivate::Undecided) {
2013+ TouchRegistry::instance()->removeCandidateOwnerForTouch(d->touchId, this);
2014+ // We still wanna know when it ends for keeping the composition time window up-to-date
2015+ TouchRegistry::instance()->addTouchWatcher(d->touchId, this);
2016+ }
2017+
2018+ Q_EMIT monitorOnlyChanged(monitorOnly);
2019+ }
2020+}
2021+
2022 void DirectionalDragArea::removeTimeConstraints()
2023 {
2024 d->setMaxTime(60 * 60 * 1000);
2025@@ -260,7 +280,10 @@
2026 unownedTouchEvent_undecided(unownedTouchEvent);
2027 break;
2028 default: // Recognized:
2029- // do nothing
2030+ if (monitorOnly) {
2031+ // Treat unowned event as if we owned it, but we are really just watching it
2032+ touchEvent_recognized(event);
2033+ }
2034 break;
2035 }
2036
2037@@ -311,7 +334,9 @@
2038 }
2039
2040 if (movedFarEnoughAlongGestureAxis()) {
2041- TouchRegistry::instance()->requestTouchOwnership(touchId, q);
2042+ if (!monitorOnly) {
2043+ TouchRegistry::instance()->requestTouchOwnership(touchId, q);
2044+ }
2045 setStatus(Recognized);
2046 setPublicPos(touchPoint->pos());
2047 setPublicScenePos(touchScenePos);
2048@@ -411,12 +436,21 @@
2049 if (recognitionIsDisabled()) {
2050 // Behave like a dumb TouchArea
2051 ddaDebug("Gesture recognition is disabled. Requesting touch ownership immediately.");
2052- TouchRegistry::instance()->requestTouchOwnership(touchId, q);
2053 setStatus(Recognized);
2054- event->accept();
2055+ if (monitorOnly) {
2056+ watchPressedTouchPoints(touchPoints);
2057+ event->ignore();
2058+ } else {
2059+ TouchRegistry::instance()->requestTouchOwnership(touchId, q);
2060+ event->accept();
2061+ }
2062 } else {
2063 // just monitor the touch points for now.
2064- TouchRegistry::instance()->addCandidateOwnerForTouch(touchId, q);
2065+ if (monitorOnly) {
2066+ watchPressedTouchPoints(touchPoints);
2067+ } else {
2068+ TouchRegistry::instance()->addCandidateOwnerForTouch(touchId, q);
2069+ }
2070
2071 setStatus(Undecided);
2072 // Let the item below have it. We will monitor it and grab it later if a gesture
2073@@ -890,5 +924,6 @@
2074 , recognitionTimer(nullptr)
2075 , timeSource(new RealTimeSource)
2076 , activeTouches(timeSource)
2077+ , monitorOnly(false)
2078 {
2079 }
2080
2081=== modified file 'plugins/Ubuntu/Gestures/DirectionalDragArea.h'
2082--- plugins/Ubuntu/Gestures/DirectionalDragArea.h 2015-05-11 07:49:36 +0000
2083+++ plugins/Ubuntu/Gestures/DirectionalDragArea.h 2016-03-11 18:12:46 +0000
2084@@ -77,6 +77,10 @@
2085 WRITE setImmediateRecognition
2086 NOTIFY immediateRecognitionChanged)
2087
2088+ // Whether we are merely monitoring touch events (in which case, we don't
2089+ // claim ownership of the touch).
2090+ Q_PROPERTY(bool monitorOnly READ monitorOnly WRITE setMonitorOnly NOTIFY monitorOnlyChanged)
2091+
2092 Q_ENUMS(Direction)
2093 public:
2094 DirectionalDragArea(QQuickItem *parent = 0);
2095@@ -100,6 +104,9 @@
2096 bool immediateRecognition() const;
2097 void setImmediateRecognition(bool enabled);
2098
2099+ bool monitorOnly() const;
2100+ void setMonitorOnly(bool monitorOnly);
2101+
2102 bool event(QEvent *e) override;
2103
2104 /*
2105@@ -123,6 +130,7 @@
2106 void touchSceneXChanged(qreal value);
2107 void touchSceneYChanged(qreal value);
2108 void immediateRecognitionChanged(bool value);
2109+ void monitorOnlyChanged(bool value);
2110
2111 protected:
2112 void touchEvent(QTouchEvent *event) override;
2113
2114=== modified file 'plugins/Ubuntu/Gestures/DirectionalDragArea_p.h'
2115--- plugins/Ubuntu/Gestures/DirectionalDragArea_p.h 2015-11-20 15:01:39 +0000
2116+++ plugins/Ubuntu/Gestures/DirectionalDragArea_p.h 2016-03-11 18:12:46 +0000
2117@@ -160,6 +160,8 @@
2118
2119 ActiveTouchesInfo activeTouches;
2120
2121+ bool monitorOnly;
2122+
2123 Q_SIGNALS:
2124 void statusChanged(Status value);
2125 };
2126
2127=== modified file 'plugins/Unity/Indicators/indicatorsmanager.cpp'
2128--- plugins/Unity/Indicators/indicatorsmanager.cpp 2015-12-02 12:02:50 +0000
2129+++ plugins/Unity/Indicators/indicatorsmanager.cpp 2016-03-11 18:12:46 +0000
2130@@ -116,7 +116,7 @@
2131 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
2132 const QString name = indicator_settings.value(QStringLiteral("Indicator Service/Name")).toString();
2133
2134- if (m_platform.isPC() && name == "indicator-keyboard") {
2135+ if (m_platform.isPC() && name == QLatin1String("indicator-keyboard")) {
2136 return; // convergence: skip this indicator until it works in Mir
2137 }
2138
2139@@ -293,7 +293,7 @@
2140 // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs)
2141 if ((new_indicator->identifier() == QStringLiteral("indicator-session") && m_platform.isMultiSession())
2142 || (new_indicator->identifier() == QStringLiteral("indicator-power") && m_platform.isPC())) {
2143- new_indicator->setProfile("desktop");
2144+ new_indicator->setProfile(QStringLiteral("desktop"));
2145 } else {
2146 new_indicator->setProfile(m_profile);
2147 }
2148
2149=== modified file 'plugins/Unity/Indicators/rootstateparser.h'
2150--- plugins/Unity/Indicators/rootstateparser.h 2014-11-11 15:28:13 +0000
2151+++ plugins/Unity/Indicators/rootstateparser.h 2016-03-11 18:12:46 +0000
2152@@ -23,6 +23,7 @@
2153
2154 class UNITYINDICATORS_EXPORT RootStateParser : public ActionStateParser
2155 {
2156+Q_OBJECT
2157 public:
2158 RootStateParser(QObject* parent = nullptr);
2159 virtual QVariant toQVariant(GVariant* state) const override;
2160
2161=== modified file 'plugins/Unity/Launcher/desktopfilehandler.cpp'
2162--- plugins/Unity/Launcher/desktopfilehandler.cpp 2015-09-30 12:43:53 +0000
2163+++ plugins/Unity/Launcher/desktopfilehandler.cpp 2016-03-11 18:12:46 +0000
2164@@ -146,9 +146,9 @@
2165 QString iconString = settings.value(QStringLiteral("Icon")).toString();
2166 QString pathString = settings.value(QStringLiteral("Path")).toString();
2167
2168- if (QFileInfo(iconString).exists()) {
2169+ if (QFileInfo::exists(iconString)) {
2170 return QFileInfo(iconString).absoluteFilePath();
2171- } else if (QFileInfo(pathString + '/' + iconString).exists()) {
2172+ } else if (QFileInfo::exists(pathString + '/' + iconString)) {
2173 return pathString + '/' + iconString;
2174 }
2175 return "image://theme/" + iconString;
2176
2177=== modified file 'plugins/Unity/Launcher/launcheritem.cpp'
2178--- plugins/Unity/Launcher/launcheritem.cpp 2015-09-14 09:11:08 +0000
2179+++ plugins/Unity/Launcher/launcheritem.cpp 2016-03-11 18:12:46 +0000
2180@@ -37,6 +37,7 @@
2181 m_alerting(false),
2182 m_quickList(new QuickListModel(this))
2183 {
2184+ Q_ASSERT(parent != nullptr);
2185 QuickListEntry nameAction;
2186 nameAction.setActionId(QStringLiteral("launch_item"));
2187 nameAction.setText(m_name);
2188
2189=== modified file 'plugins/Unity/Launcher/launcheritem.h'
2190--- plugins/Unity/Launcher/launcheritem.h 2015-07-23 14:13:57 +0000
2191+++ plugins/Unity/Launcher/launcheritem.h 2016-03-11 18:12:46 +0000
2192@@ -32,7 +32,7 @@
2193 {
2194 Q_OBJECT
2195 public:
2196- LauncherItem(const QString &appId, const QString &name, const QString &icon, QObject *parent = 0);
2197+ LauncherItem(const QString &appId, const QString &name, const QString &icon, QObject *parent);
2198
2199 QString appId() const override;
2200 QString name() const override;
2201
2202=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
2203--- plugins/Unity/Launcher/launchermodel.cpp 2015-09-14 09:11:08 +0000
2204+++ plugins/Unity/Launcher/launchermodel.cpp 2016-03-11 18:12:46 +0000
2205@@ -103,7 +103,7 @@
2206 LauncherItem *item = m_list.at(index);
2207 if (!item->focused()) {
2208 item->setAlerting(alerting);
2209- Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleAlerting);
2210+ Q_EMIT dataChanged(modelIndex, modelIndex, {RoleAlerting});
2211 }
2212 }
2213 }
2214@@ -389,7 +389,8 @@
2215 if (countVisible && desktopFile.isValid()) {
2216 LauncherItem *item = new LauncherItem(appId,
2217 desktopFile.displayName(),
2218- desktopFile.icon());
2219+ desktopFile.icon(),
2220+ this);
2221 item->setCountVisible(true);
2222 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
2223 m_list.append(item);
2224@@ -414,10 +415,19 @@
2225 } else {
2226 int idx = m_list.indexOf(item);
2227 item->setName(desktopFile.displayName());
2228- item->setIcon(desktopFile.icon());
2229 item->setPinned(item->pinned()); // update pinned text if needed
2230 item->setRunning(item->running());
2231- Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleIcon, RoleRunning});
2232+ Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning});
2233+
2234+ const QString oldIcon = item->icon();
2235+ if (oldIcon == desktopFile.icon()) { // same icon file, perhaps different contents, simulate changing the icon name to force reload
2236+ item->setIcon(QString());
2237+ Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
2238+ }
2239+
2240+ // now set the icon for real
2241+ item->setIcon(desktopFile.icon());
2242+ Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
2243 }
2244 }
2245
2246@@ -489,7 +499,7 @@
2247 if (idx >= 0) {
2248 LauncherItem *item = m_list.at(idx);
2249 setAlerting(item->appId(), true);
2250- Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleAlerting);
2251+ Q_EMIT dataChanged(index(idx), index(idx), {RoleAlerting});
2252 }
2253 }
2254
2255
2256=== modified file 'plugins/Unity/Launcher/launchermodel.h'
2257--- plugins/Unity/Launcher/launchermodel.h 2015-07-29 12:32:57 +0000
2258+++ plugins/Unity/Launcher/launchermodel.h 2016-03-11 18:12:46 +0000
2259@@ -38,7 +38,7 @@
2260 Q_OBJECT
2261
2262 public:
2263- LauncherModel(QObject *parent = 0);
2264+ LauncherModel(QObject *parent = nullptr);
2265 ~LauncherModel();
2266
2267 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
2268
2269=== modified file 'plugins/Utils/CMakeLists.txt'
2270--- plugins/Utils/CMakeLists.txt 2016-02-08 09:37:48 +0000
2271+++ plugins/Utils/CMakeLists.txt 2016-03-11 18:12:46 +0000
2272@@ -17,12 +17,13 @@
2273 unitysortfilterproxymodelqml.cpp
2274 Timer.cpp
2275 unitymenumodelpaths.cpp
2276- windowkeysfilter.cpp
2277+ windowinputfilter.cpp
2278 windowscreenshotprovider.cpp
2279 easingcurve.cpp
2280 windowstatestorage.cpp
2281 timezoneFormatter.cpp
2282 inputeventgenerator.cpp
2283+ deviceconfigparser.cpp
2284 plugin.cpp
2285 )
2286
2287
2288=== modified file 'plugins/Utils/Utils.qmltypes'
2289--- plugins/Utils/Utils.qmltypes 2015-09-03 11:08:46 +0000
2290+++ plugins/Utils/Utils.qmltypes 2016-03-11 18:12:46 +0000
2291@@ -147,10 +147,10 @@
2292 }
2293 }
2294 Component {
2295- name: "WindowKeysFilter"
2296+ name: "WindowInputFilter"
2297 defaultProperty: "data"
2298 prototype: "QQuickItem"
2299- exports: ["Utils/WindowKeysFilter 0.1"]
2300+ exports: ["Utils/WindowInputFilter 0.1"]
2301 exportMetaObjectRevisions: [0]
2302 }
2303 Component {
2304
2305=== added file 'plugins/Utils/deviceconfigparser.cpp'
2306--- plugins/Utils/deviceconfigparser.cpp 1970-01-01 00:00:00 +0000
2307+++ plugins/Utils/deviceconfigparser.cpp 2016-03-11 18:12:46 +0000
2308@@ -0,0 +1,150 @@
2309+/*
2310+ * Copyright 2016 Canonical Ltd.
2311+ *
2312+ * This program is free software; you can redistribute it and/or modify
2313+ * it under the terms of the GNU Lesser General Public License as published by
2314+ * the Free Software Foundation; version 3.
2315+ *
2316+ * This program is distributed in the hope that it will be useful,
2317+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2318+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2319+ * GNU Lesser General Public License for more details.
2320+ *
2321+ * You should have received a copy of the GNU Lesser General Public License
2322+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2323+ */
2324+
2325+#include "deviceconfigparser.h"
2326+
2327+#include <QSettings>
2328+#include <QFileInfo>
2329+#include <QDebug>
2330+#include <QStandardPaths>
2331+
2332+DeviceConfigParser::DeviceConfigParser(QObject *parent): QObject(parent)
2333+{
2334+ QString path;
2335+ Q_FOREACH (const QString &standardPath, QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation)) {
2336+ if (QFileInfo(standardPath + "/devices.conf").exists()) {
2337+ path = standardPath + "/devices.conf";
2338+ break;
2339+ }
2340+ }
2341+
2342+ if (path.isEmpty()) {
2343+ path = "/etc/ubuntu/devices.conf";
2344+ }
2345+ qDebug() << "Using" << path << "as device configuration file";
2346+ m_config = new QSettings(path, QSettings::IniFormat, this);
2347+}
2348+
2349+QString DeviceConfigParser::name() const
2350+{
2351+ return m_name;
2352+}
2353+
2354+void DeviceConfigParser::setName(const QString &name)
2355+{
2356+ if (m_name == name) {
2357+ return;
2358+ }
2359+ m_name = name;
2360+ Q_EMIT changed();
2361+}
2362+
2363+Qt::ScreenOrientation DeviceConfigParser::primaryOrientation() const
2364+{
2365+ return stringToOrientation(readOrientationFromConfig("PrimaryOrientation"), Qt::PrimaryOrientation);
2366+}
2367+
2368+Qt::ScreenOrientations DeviceConfigParser::supportedOrientations() const
2369+{
2370+ QStringList values = readOrientationsFromConfig("SupportedOrientations");
2371+ if (values.isEmpty()) {
2372+ return Qt::PortraitOrientation
2373+ | Qt::InvertedPortraitOrientation
2374+ | Qt::LandscapeOrientation
2375+ | Qt::InvertedLandscapeOrientation;
2376+ }
2377+
2378+ Qt::ScreenOrientations ret = Qt::PrimaryOrientation;
2379+ Q_FOREACH(const QString &orientationString, values) {
2380+ ret |= stringToOrientation(orientationString, Qt::PrimaryOrientation);
2381+ }
2382+ return ret;
2383+}
2384+
2385+Qt::ScreenOrientation DeviceConfigParser::landscapeOrientation() const
2386+{
2387+ return stringToOrientation(readOrientationFromConfig("LandscapeOrientation"), Qt::LandscapeOrientation);
2388+}
2389+
2390+Qt::ScreenOrientation DeviceConfigParser::invertedLandscapeOrientation() const
2391+{
2392+ return stringToOrientation(readOrientationFromConfig("InvertedLandscapeOrientation"), Qt::InvertedLandscapeOrientation);
2393+}
2394+
2395+Qt::ScreenOrientation DeviceConfigParser::portraitOrientation() const
2396+{
2397+ return stringToOrientation(readOrientationFromConfig("PortraitOrientation"), Qt::PortraitOrientation);
2398+}
2399+
2400+Qt::ScreenOrientation DeviceConfigParser::invertedPortraitOrientation() const
2401+{
2402+ return stringToOrientation(readOrientationFromConfig("InvertedPortraitOrientation"), Qt::InvertedPortraitOrientation);
2403+}
2404+
2405+QString DeviceConfigParser::category() const
2406+{
2407+ QStringList supportedValues = {"phone", "tablet", "desktop"};
2408+ m_config->beginGroup(m_name);
2409+ QString value = m_config->value("Category", "phone").toString();
2410+ if (!supportedValues.contains(value)) {
2411+ qWarning().nospace().noquote() << "Unknown option \"" << value << "\" in " << m_config->fileName()
2412+ << ". Supported options are: " << supportedValues.join(", ") << ".";
2413+ return "phone";
2414+ }
2415+ m_config->endGroup();
2416+ return value;
2417+}
2418+
2419+QStringList DeviceConfigParser::readOrientationsFromConfig(const QString &key) const
2420+{
2421+ m_config->beginGroup(m_name);
2422+
2423+ QStringList ret;
2424+ if (m_config->contains(key)) {
2425+ ret = m_config->value(key).toStringList();
2426+ }
2427+
2428+ m_config->endGroup();
2429+ return ret;
2430+}
2431+
2432+QString DeviceConfigParser::readOrientationFromConfig(const QString &key) const
2433+{
2434+ QStringList ret = readOrientationsFromConfig(key);
2435+ return ret.count() > 0 ? ret.first() : QString();
2436+}
2437+
2438+Qt::ScreenOrientation DeviceConfigParser::stringToOrientation(const QString &orientationString, Qt::ScreenOrientation defaultValue) const
2439+{
2440+ if (orientationString == "Landscape") {
2441+ return Qt::LandscapeOrientation;
2442+ }
2443+ if (orientationString == "InvertedLandscape") {
2444+ return Qt::InvertedLandscapeOrientation;
2445+ }
2446+ if (orientationString == "Portrait") {
2447+ return Qt::PortraitOrientation;
2448+ }
2449+ if (orientationString == "InvertedPortrait") {
2450+ return Qt::InvertedPortraitOrientation;
2451+ }
2452+ if (!orientationString.isEmpty()) {
2453+ // Some option we don't know. Give some hint on what went wrong.
2454+ qWarning().nospace().noquote() << "Unknown option \"" << orientationString << "\" in " << m_config->fileName()
2455+ << ". Supported options are: Landscape, InvertedLandscape, Portrait and InvertedPortrait.";
2456+ }
2457+ return defaultValue;
2458+}
2459
2460=== added file 'plugins/Utils/deviceconfigparser.h'
2461--- plugins/Utils/deviceconfigparser.h 1970-01-01 00:00:00 +0000
2462+++ plugins/Utils/deviceconfigparser.h 2016-03-11 18:12:46 +0000
2463@@ -0,0 +1,62 @@
2464+/*
2465+ * Copyright 2016 Canonical Ltd.
2466+ *
2467+ * This program is free software; you can redistribute it and/or modify
2468+ * it under the terms of the GNU Lesser General Public License as published by
2469+ * the Free Software Foundation; version 3.
2470+ *
2471+ * This program is distributed in the hope that it will be useful,
2472+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2473+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2474+ * GNU Lesser General Public License for more details.
2475+ *
2476+ * You should have received a copy of the GNU Lesser General Public License
2477+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2478+ */
2479+
2480+#ifndef DEVICECONFIGPARSER_H
2481+#define DEVICECONFIGPARSER_H
2482+
2483+#include <QObject>
2484+#include <QSettings>
2485+
2486+class DeviceConfigParser: public QObject
2487+{
2488+ Q_OBJECT
2489+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY changed)
2490+
2491+ Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY changed)
2492+ Q_PROPERTY(Qt::ScreenOrientations supportedOrientations READ supportedOrientations NOTIFY changed)
2493+ Q_PROPERTY(Qt::ScreenOrientation landscapeOrientation READ landscapeOrientation NOTIFY changed)
2494+ Q_PROPERTY(Qt::ScreenOrientation invertedLandscapeOrientation READ invertedLandscapeOrientation NOTIFY changed)
2495+ Q_PROPERTY(Qt::ScreenOrientation portraitOrientation READ portraitOrientation NOTIFY changed)
2496+ Q_PROPERTY(Qt::ScreenOrientation invertedPortraitOrientation READ invertedPortraitOrientation NOTIFY changed)
2497+ Q_PROPERTY(QString category READ category NOTIFY changed)
2498+
2499+public:
2500+ DeviceConfigParser(QObject *parent = nullptr);
2501+
2502+ QString name() const;
2503+ void setName(const QString &name);
2504+
2505+ Qt::ScreenOrientation primaryOrientation() const;
2506+ Qt::ScreenOrientations supportedOrientations() const;
2507+ Qt::ScreenOrientation landscapeOrientation() const;
2508+ Qt::ScreenOrientation invertedLandscapeOrientation() const;
2509+ Qt::ScreenOrientation portraitOrientation() const;
2510+ Qt::ScreenOrientation invertedPortraitOrientation() const;
2511+ QString category() const;
2512+
2513+Q_SIGNALS:
2514+ void changed();
2515+
2516+private:
2517+ QString m_name;
2518+ QSettings *m_config;
2519+
2520+ QStringList readOrientationsFromConfig(const QString &key) const;
2521+ QString readOrientationFromConfig(const QString &key) const;
2522+ Qt::ScreenOrientation stringToOrientation(const QString &orientationString, Qt::ScreenOrientation defaultValue) const;
2523+};
2524+
2525+#endif
2526
2527=== modified file 'plugins/Utils/plugin.cpp'
2528--- plugins/Utils/plugin.cpp 2016-01-29 11:52:14 +0000
2529+++ plugins/Utils/plugin.cpp 2016-03-11 18:12:46 +0000
2530@@ -30,13 +30,14 @@
2531 #include "qlimitproxymodelqml.h"
2532 #include "unitysortfilterproxymodelqml.h"
2533 #include "unitymenumodelpaths.h"
2534-#include "windowkeysfilter.h"
2535+#include "windowinputfilter.h"
2536 #include "windowscreenshotprovider.h"
2537 #include "windowstatestorage.h"
2538 #include "constants.h"
2539 #include "timezoneFormatter.h"
2540 #include "applicationsfiltermodel.h"
2541 #include "inputeventgenerator.h"
2542+#include "deviceconfigparser.h"
2543
2544 static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
2545 {
2546@@ -60,7 +61,7 @@
2547 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
2548 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
2549 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
2550- qmlRegisterType<WindowKeysFilter>(uri, 0, 1, "WindowKeysFilter");
2551+ qmlRegisterType<WindowInputFilter>(uri, 0, 1, "WindowInputFilter");
2552 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
2553 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
2554 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
2555@@ -70,6 +71,7 @@
2556 qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
2557 qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel");
2558 qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator");
2559+ qmlRegisterType<DeviceConfigParser>(uri, 0, 1, "DeviceConfigParser");
2560 }
2561
2562 void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
2563
2564=== modified file 'plugins/Utils/timezoneFormatter.cpp'
2565--- plugins/Utils/timezoneFormatter.cpp 2015-11-20 15:01:39 +0000
2566+++ plugins/Utils/timezoneFormatter.cpp 2016-03-11 18:12:46 +0000
2567@@ -33,3 +33,13 @@
2568 }
2569 return QString();
2570 }
2571+
2572+QString TimezoneFormatter::currentTimeInTimezoneWithAbbrev(const QVariant &tzId) const
2573+{
2574+ QTimeZone tz(tzId.toByteArray());
2575+ if (tz.isValid()) {
2576+ const QDateTime now = QDateTime::currentDateTime().toTimeZone(tz);
2577+ return QStringLiteral("%1 %2").arg(now.time().toString(QStringLiteral("h:mm"))).arg(tz.abbreviation(now));
2578+ }
2579+ return QString();
2580+}
2581
2582=== modified file 'plugins/Utils/timezoneFormatter.h'
2583--- plugins/Utils/timezoneFormatter.h 2015-09-17 13:42:15 +0000
2584+++ plugins/Utils/timezoneFormatter.h 2016-03-11 18:12:46 +0000
2585@@ -27,6 +27,7 @@
2586 ~TimezoneFormatter() = default;
2587
2588 Q_INVOKABLE QString currentTimeInTimezone(const QVariant &tzId) const;
2589+ Q_INVOKABLE QString currentTimeInTimezoneWithAbbrev(const QVariant &tzId) const;
2590 };
2591
2592 #endif
2593
2594=== renamed file 'plugins/Utils/windowkeysfilter.cpp' => 'plugins/Utils/windowinputfilter.cpp'
2595--- plugins/Utils/windowkeysfilter.cpp 2015-10-22 17:37:26 +0000
2596+++ plugins/Utils/windowinputfilter.cpp 2016-03-11 18:12:46 +0000
2597@@ -16,36 +16,34 @@
2598 * Author: Daniel d'Andrada <daniel.dandrada@canonical.com>
2599 */
2600
2601-#include "windowkeysfilter.h"
2602+#include "windowinputfilter.h"
2603
2604 #include <QQuickWindow>
2605
2606-WindowKeysFilter::WindowKeysFilter(QQuickItem *parent)
2607+WindowInputFilter::WindowInputFilter(QQuickItem *parent)
2608 : QQuickItem(parent),
2609- m_currentEventTimestamp(0)
2610+ m_lastInputTimestamp(0)
2611 {
2612 connect(this, &QQuickItem::windowChanged,
2613- this, &WindowKeysFilter::setupFilterOnWindow);
2614+ this, &WindowInputFilter::setupFilterOnWindow);
2615 }
2616
2617-bool WindowKeysFilter::eventFilter(QObject *watched, QEvent *event)
2618+bool WindowInputFilter::eventFilter(QObject *watched, QEvent *event)
2619 {
2620 Q_ASSERT(!m_filteredWindow.isNull());
2621 Q_ASSERT(watched == static_cast<QObject*>(m_filteredWindow.data()));
2622 Q_UNUSED(watched);
2623
2624+ QInputEvent *inputEvent = dynamic_cast<QInputEvent*>(event);
2625+ if (inputEvent) {
2626+ m_lastInputTimestamp = inputEvent->timestamp();
2627+ Q_EMIT lastInputTimestampChanged();
2628+ }
2629+
2630 if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
2631 // Let QML see this event and decide if it does not want it
2632 event->accept();
2633-
2634- m_currentEventTimestamp = static_cast<QInputEvent*>(event)->timestamp();
2635- Q_EMIT currentEventTimestampChanged();
2636-
2637 QCoreApplication::sendEvent(this, event);
2638-
2639- m_currentEventTimestamp = 0;
2640- Q_EMIT currentEventTimestampChanged();
2641-
2642 return event->isAccepted();
2643 } else {
2644 // Not interested
2645@@ -53,7 +51,7 @@
2646 }
2647 }
2648
2649-void WindowKeysFilter::setupFilterOnWindow(QQuickWindow *window)
2650+void WindowInputFilter::setupFilterOnWindow(QQuickWindow *window)
2651 {
2652 if (!m_filteredWindow.isNull()) {
2653 m_filteredWindow->removeEventFilter(this);
2654@@ -66,7 +64,7 @@
2655 }
2656 }
2657
2658-ulong WindowKeysFilter::currentEventTimestamp() const
2659+ulong WindowInputFilter::lastInputTimestamp() const
2660 {
2661- return m_currentEventTimestamp;
2662+ return m_lastInputTimestamp;
2663 }
2664
2665=== renamed file 'plugins/Utils/windowkeysfilter.h' => 'plugins/Utils/windowinputfilter.h'
2666--- plugins/Utils/windowkeysfilter.h 2015-10-22 17:37:26 +0000
2667+++ plugins/Utils/windowinputfilter.h 2016-03-11 18:12:46 +0000
2668@@ -16,8 +16,8 @@
2669 * Author: Daniel d'Andrada <daniel.dandrada@canonical.com>
2670 */
2671
2672-#ifndef UNITY_WINDOWKEYSFILTER_H
2673-#define UNITY_WINDOWKEYSFILTER_H
2674+#ifndef UNITY_WINDOWINPUTFILTER_H
2675+#define UNITY_WINDOWINPUTFILTER_H
2676
2677 #include <QQuickItem>
2678 #include <QPointer>
2679@@ -29,30 +29,30 @@
2680 accepted ones will be filtered out. Events are accepted by default, so make sure you reject
2681 the keys you're not interested in.
2682
2683- If more than one WindowKeysFilter exist in the same QML scene (and thus in the same QQuickWindow)
2684+ If more than one WindowInputFilter exist in the same QML scene (and thus in the same QQuickWindow)
2685 they will be called in the order of creation, which can be tricky to assess. So the best practice
2686- is to have at most one WindowKeysFilter per QML scene.
2687+ is to have at most one WindowInputFilter per QML scene.
2688 */
2689-class WindowKeysFilter : public QQuickItem
2690+class WindowInputFilter : public QQuickItem
2691 {
2692 Q_OBJECT
2693- Q_PROPERTY(ulong currentEventTimestamp READ currentEventTimestamp NOTIFY currentEventTimestampChanged)
2694+ Q_PROPERTY(ulong lastInputTimestamp READ lastInputTimestamp NOTIFY lastInputTimestampChanged)
2695 public:
2696- WindowKeysFilter(QQuickItem *parent = 0);
2697+ WindowInputFilter(QQuickItem *parent = 0);
2698
2699 bool eventFilter(QObject *watched, QEvent *event) override;
2700
2701- ulong currentEventTimestamp() const;
2702+ ulong lastInputTimestamp() const;
2703
2704 Q_SIGNALS:
2705- void currentEventTimestampChanged();
2706+ void lastInputTimestampChanged();
2707
2708 private Q_SLOTS:
2709 void setupFilterOnWindow(QQuickWindow *window);
2710
2711 private:
2712 QPointer<QQuickWindow> m_filteredWindow;
2713- ulong m_currentEventTimestamp;
2714+ ulong m_lastInputTimestamp;
2715 };
2716
2717-#endif // UNITY_WINDOWKEYSFILTER_H
2718+#endif // UNITY_WINDOWINPUTFILTER_H
2719
2720=== modified file 'plugins/Wizard/CMakeLists.txt'
2721--- plugins/Wizard/CMakeLists.txt 2014-11-14 17:47:00 +0000
2722+++ plugins/Wizard/CMakeLists.txt 2016-03-11 18:12:46 +0000
2723@@ -1,10 +1,16 @@
2724+include_directories(${GLIB_INCLUDE_DIRS} ${GEONAMES_INCLUDE_DIRS})
2725+
2726 add_library(Wizard-qml MODULE
2727 plugin.cpp
2728 PageList.cpp
2729 System.cpp
2730+ LocalePlugin.cpp
2731+ timezonemodel.cpp
2732+ Status.cpp
2733 )
2734
2735-qt5_use_modules(Wizard-qml DBus Qml)
2736+qt5_use_modules(Wizard-qml DBus Qml Concurrent)
2737+target_link_libraries(Wizard-qml ${GLIB_LDFLAGS} ${GEONAMES_LDFLAGS})
2738 add_unity8_plugin(Wizard 0.1 Wizard TARGETS Wizard-qml)
2739
2740 set(POLKIT_LIB_DIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1")
2741
2742=== added file 'plugins/Wizard/LocalePlugin.cpp'
2743--- plugins/Wizard/LocalePlugin.cpp 1970-01-01 00:00:00 +0000
2744+++ plugins/Wizard/LocalePlugin.cpp 2016-03-11 18:12:46 +0000
2745@@ -0,0 +1,291 @@
2746+/*
2747+ * Copyright (C) 2015 Canonical Ltd.
2748+ *
2749+ * This program is free software: you can redistribute it and/or modify it
2750+ * under the terms of the GNU General Public License version 3, as published
2751+ * by the Free Software Foundation.
2752+ *
2753+ * This program is distributed in the hope that it will be useful, but
2754+ * WITHOUT ANY WARRANTY; without even the implied warranties of
2755+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2756+ * PURPOSE. See the GNU General Public License for more details.
2757+ *
2758+ * You should have received a copy of the GNU General Public License along
2759+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2760+ */
2761+
2762+#include <QLocale>
2763+#include <QStringList>
2764+
2765+#include <libintl.h>
2766+
2767+#include "LocalePlugin.h"
2768+
2769+class LocalePrivate {
2770+public:
2771+ LocalePrivate() {
2772+ m_mccCodes = QHash<int, QString>
2773+ ({{202,"gr"},
2774+ {204,"nl"},
2775+ {206,"be"},
2776+ {208,"fr"},
2777+ {212,"mc"},
2778+ {213,"ad"},
2779+ {214,"es"},
2780+ {216,"hu"},
2781+ {218,"ba"},
2782+ {219,"hr"},
2783+ {220,"rs"},
2784+ {222,"it"},
2785+ {226,"ro"},
2786+ {228,"ch"},
2787+ {230,"cz"},
2788+ {231,"sk"},
2789+ {232,"at"},
2790+ {234,"gb"},
2791+ {235,"gb"},
2792+ {238,"dk"},
2793+ {240,"se"},
2794+ {242,"no"},
2795+ {244,"fi"},
2796+ {246,"lt"},
2797+ {247,"lv"},
2798+ {248,"ee"},
2799+ {250,"ru"},
2800+ {255,"ua"},
2801+ {257,"by"},
2802+ {259,"md"},
2803+ {260,"pl"},
2804+ {262,"de"},
2805+ {266,"gi"},
2806+ {268,"pt"},
2807+ {270,"lu"},
2808+ {272,"ie"},
2809+ {274,"is"},
2810+ {276,"al"},
2811+ {278,"mt"},
2812+ {280,"cy"},
2813+ {282,"ge"},
2814+ {283,"am"},
2815+ {284,"bg"},
2816+ {286,"tr"},
2817+ {288,"fo"},
2818+ {289,"ge"},
2819+ {290,"gl"},
2820+ {292,"sm"},
2821+ {293,"si"},
2822+ {294,"mk"},
2823+ {295,"li"},
2824+ {297,"me"},
2825+ {302,"ca"},
2826+ {308,"pm"},
2827+ {310,"gu"},
2828+ {310,"us"},
2829+ {311,"gu"},
2830+ {311,"us"},
2831+ {312,"us"},
2832+ {316,"us"},
2833+ {330,"pr"},
2834+ {334,"mx"},
2835+ {338,"jm"},
2836+ {340,"fg"},
2837+ {340,"gp"},
2838+ {340,"mq"},
2839+ {342,"bb"},
2840+ {344,"ag"},
2841+ {346,"ky"},
2842+ {348,"vg"},
2843+ {350,"bm"},
2844+ {352,"gd"},
2845+ {354,"ms"},
2846+ {356,"kn"},
2847+ {358,"lc"},
2848+ {360,"vc"},
2849+ {362,"an"},
2850+ {362,"cw"},
2851+ {363,"aw"},
2852+ {364,"bs"},
2853+ {365,"ai"},
2854+ {366,"dm"},
2855+ {368,"cu"},
2856+ {370,"do"},
2857+ {372,"ht"},
2858+ {374,"tt"},
2859+ {376,"tc"},
2860+ {376,"vi"},
2861+ {400,"az"},
2862+ {401,"kz"},
2863+ {402,"bt"},
2864+ {404,"in"},
2865+ {405,"in"},
2866+ {410,"pk"},
2867+ {412,"af"},
2868+ {413,"lk"},
2869+ {414,"mm"},
2870+ {415,"lb"},
2871+ {416,"jo"},
2872+ {417,"sy"},
2873+ {418,"iq"},
2874+ {419,"kw"},
2875+ {420,"sa"},
2876+ {421,"ye"},
2877+ {422,"om"},
2878+ {424,"ae"},
2879+ {425,"il"},
2880+ {425,"ps"},
2881+ {426,"bh"},
2882+ {427,"qa"},
2883+ {428,"mn"},
2884+ {429,"np"},
2885+ {430,"ae"},
2886+ {431,"ae"},
2887+ {432,"ir"},
2888+ {434,"uz"},
2889+ {436,"tk"},
2890+ {437,"kg"},
2891+ {438,"tm"},
2892+ {440,"jp"},
2893+ {441,"jp"},
2894+ {450,"kr"},
2895+ {452,"vn"},
2896+ {454,"hk"},
2897+ {455,"mo"},
2898+ {456,"kh"},
2899+ {457,"la"},
2900+ {460,"cn"},
2901+ {466,"tw"},
2902+ {467,"kp"},
2903+ {470,"bd"},
2904+ {472,"mv"},
2905+ {502,"my"},
2906+ {505,"au"},
2907+ {510,"id"},
2908+ {514,"tp"},
2909+ {515,"ph"},
2910+ {520,"th"},
2911+ {525,"sg"},
2912+ {528,"bn"},
2913+ {530,"nz"},
2914+ {537,"pg"},
2915+ {539,"to"},
2916+ {540,"sb"},
2917+ {541,"vu"},
2918+ {542,"fj"},
2919+ {544,"as"},
2920+ {545,"ki"},
2921+ {546,"nc"},
2922+ {547,"pf"},
2923+ {548,"ck"},
2924+ {549,"ws"},
2925+ {550,"fm"},
2926+ {552,"pw"},
2927+ {553,"tv"},
2928+ {555,"nu"},
2929+ {602,"eg"},
2930+ {603,"dz"},
2931+ {604,"ma"},
2932+ {605,"tn"},
2933+ {606,"ly"},
2934+ {607,"gm"},
2935+ {608,"sn"},
2936+ {609,"mr"},
2937+ {610,"ml"},
2938+ {611,"gn"},
2939+ {612,"ci"},
2940+ {613,"bf"},
2941+ {614,"ne"},
2942+ {615,"tg"},
2943+ {616,"bj"},
2944+ {617,"mu"},
2945+ {618,"lr"},
2946+ {619,"sl"},
2947+ {620,"gh"},
2948+ {621,"ng"},
2949+ {622,"td"},
2950+ {623,"cf"},
2951+ {624,"cm"},
2952+ {625,"cv"},
2953+ {626,"st"},
2954+ {627,"gq"},
2955+ {628,"ga"},
2956+ {629,"cg"},
2957+ {630,"cd"},
2958+ {631,"ao"},
2959+ {632,"gw"},
2960+ {633,"sc"},
2961+ {634,"sd"},
2962+ {635,"rw"},
2963+ {636,"et"},
2964+ {637,"so"},
2965+ {638,"dj"},
2966+ {639,"ke"},
2967+ {640,"tz"},
2968+ {641,"ug"},
2969+ {642,"bi"},
2970+ {643,"mz"},
2971+ {645,"zm"},
2972+ {646,"mg"},
2973+ {647,"re"},
2974+ {648,"zw"},
2975+ {649,"na"},
2976+ {650,"mw"},
2977+ {651,"ls"},
2978+ {652,"bw"},
2979+ {653,"sz"},
2980+ {654,"km"},
2981+ {655,"za"},
2982+ {657,"er"},
2983+ {659,"ss"},
2984+ {702,"bz"},
2985+ {704,"gt"},
2986+ {706,"sv"},
2987+ {708,"hn"},
2988+ {710,"ni"},
2989+ {712,"cr"},
2990+ {714,"pa"},
2991+ {716,"pe"},
2992+ {722,"ar"},
2993+ {724,"br"},
2994+ {730,"cl"},
2995+ {732,"co"},
2996+ {734,"ve"},
2997+ {736,"bo"},
2998+ {738,"gy"},
2999+ {740,"ec"},
3000+ {744,"py"},
3001+ {746,"sr"},
3002+ {748,"uy"},
3003+ {750,"fk"}}
3004+ );
3005+ }
3006+
3007+ QString mccToCountryCode(int mcc) const {
3008+ return m_mccCodes.value(mcc, "us").toUpper();
3009+ }
3010+
3011+private:
3012+ // MCC = Mobile Country Code, see https://en.wikipedia.org/wiki/Mobile_country_code
3013+ QHash<int,QString> m_mccCodes;
3014+};
3015+
3016+Q_GLOBAL_STATIC(LocalePrivate, d)
3017+
3018+LocaleAttached::LocaleAttached(QObject* parent)
3019+ : QObject(parent)
3020+{
3021+}
3022+
3023+QString LocaleAttached::mccToCountryCode(int mcc) const
3024+{
3025+ return d->mccToCountryCode(mcc);
3026+}
3027+
3028+LocalePlugin::LocalePlugin(QObject* parent)
3029+ : QObject(parent)
3030+{
3031+}
3032+
3033+LocaleAttached* LocalePlugin::qmlAttachedProperties(QObject* parent)
3034+{
3035+ return new LocaleAttached(parent);
3036+}
3037
3038=== added file 'plugins/Wizard/LocalePlugin.h'
3039--- plugins/Wizard/LocalePlugin.h 1970-01-01 00:00:00 +0000
3040+++ plugins/Wizard/LocalePlugin.h 2016-03-11 18:12:46 +0000
3041@@ -0,0 +1,58 @@
3042+/*
3043+ * Copyright (C) 2015 Canonical Ltd.
3044+ *
3045+ * This program is free software: you can redistribute it and/or modify it
3046+ * under the terms of the GNU General Public License version 3, as published
3047+ * by the Free Software Foundation.
3048+ *
3049+ * This program is distributed in the hope that it will be useful, but
3050+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3051+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
3052+ * PURPOSE. See the GNU General Public License for more details.
3053+ *
3054+ * You should have received a copy of the GNU General Public License along
3055+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3056+ */
3057+
3058+#ifndef LOCALE_PLUGIN_H
3059+#define LOCALE_PLUGIN_H
3060+
3061+#include <QObject>
3062+#include <QString>
3063+#include <QJsonObject>
3064+#include <QtQml>
3065+
3066+class LocaleAttached: public QObject
3067+{
3068+ Q_OBJECT
3069+protected:
3070+ explicit LocaleAttached(QObject *parent = 0);
3071+
3072+public:
3073+ Q_INVOKABLE QString mccToCountryCode(int mcc) const;
3074+
3075+ friend class LocalePlugin;
3076+};
3077+
3078+/**
3079+ * A simplified wrapper around QLocale.
3080+ *
3081+ * The wrapper is implemented as an attached property, which makes it possible
3082+ * to use it as if its methods were static:
3083+ *
3084+ * @code
3085+ * var langs = LocalePlugin.languages();
3086+ * @endcode
3087+ */
3088+class LocalePlugin: public QObject
3089+{
3090+ Q_OBJECT
3091+public:
3092+ explicit LocalePlugin(QObject *parent = 0);
3093+
3094+ static LocaleAttached* qmlAttachedProperties(QObject *parent);
3095+};
3096+
3097+QML_DECLARE_TYPEINFO(LocalePlugin, QML_HAS_ATTACHED_PROPERTIES)
3098+
3099+#endif // LOCALE_PLUGIN_H
3100
3101=== modified file 'plugins/Wizard/PageList.cpp'
3102--- plugins/Wizard/PageList.cpp 2015-09-14 09:11:08 +0000
3103+++ plugins/Wizard/PageList.cpp 2016-03-11 18:12:46 +0000
3104@@ -40,20 +40,20 @@
3105 m_index(-1),
3106 m_pages()
3107 {
3108- QString qmlSuffix = QStringLiteral(".qml");
3109- QString disabledSuffix = QStringLiteral(".disabled");
3110+ const QString qmlSuffix = QStringLiteral(".qml");
3111+ const QString disabledSuffix = QStringLiteral(".disabled");
3112 QSet<QString> disabledPages;
3113 QStringList dataDirs;
3114
3115 if (!isRunningInstalled() && getenv("WIZARD_TESTING") == nullptr) {
3116- dataDirs = QStringList() << qmlDirectory();
3117+ dataDirs << qmlDirectory();
3118 } else {
3119 dataDirs = shellDataDirs();
3120 }
3121
3122 Q_FOREACH(const QString &dataDir, dataDirs) {
3123 QDir dir(dataDir + "/Wizard/Pages");
3124- QStringList entries = dir.entryList(QStringList(QStringLiteral("[0-9]*")), QDir::Files | QDir::Readable);
3125+ const QStringList entries = dir.entryList(QStringList(QStringLiteral("[0-9]*")), QDir::Files | QDir::Readable);
3126 Q_FOREACH(const QString &entry, entries) {
3127 if (!m_pages.contains(entry) && entry.endsWith(qmlSuffix))
3128 m_pages.insert(entry, dir.absoluteFilePath(entry));
3129
3130=== added file 'plugins/Wizard/Status.cpp'
3131--- plugins/Wizard/Status.cpp 1970-01-01 00:00:00 +0000
3132+++ plugins/Wizard/Status.cpp 2016-03-11 18:12:46 +0000
3133@@ -0,0 +1,143 @@
3134+/*
3135+ * Copyright (C) 2015 Canonical Ltd.
3136+ *
3137+ * This program is free software: you can redistribute it and/or modify it
3138+ * under the terms of the GNU General Public License version 3, as published
3139+ * by the Free Software Foundation.
3140+ *
3141+ * This program is distributed in the hope that it will be useful, but
3142+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3143+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
3144+ * PURPOSE. See the GNU General Public License for more details.
3145+ *
3146+ * You should have received a copy of the GNU General Public License along
3147+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3148+ */
3149+
3150+#include <QDebug>
3151+#include <QDBusConnection>
3152+
3153+#include "Status.h"
3154+
3155+Status::Status()
3156+{
3157+ initNM();
3158+ initUPower();
3159+}
3160+
3161+void Status::initNM()
3162+{
3163+ m_nmIface = new QDBusInterface("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager",
3164+ QDBusConnection::systemBus(), this);
3165+
3166+ QDBusConnection::systemBus().connect("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", "PropertiesChanged",
3167+ this, SLOT(onNMPropertiesChanged(QVariantMap)));
3168+}
3169+
3170+void Status::onNMPropertiesChanged(const QVariantMap &changedProps)
3171+{
3172+ if (changedProps.contains("State") || changedProps.contains("Connectivity")) {
3173+ Q_EMIT onlineChanged();
3174+ Q_EMIT networkIconChanged();
3175+ }
3176+
3177+ if (changedProps.contains("PrimaryConnection") || changedProps.contains("SpecificObject") || changedProps.contains("Strength")) {
3178+ Q_EMIT networkIconChanged();
3179+ }
3180+}
3181+
3182+bool Status::online() const
3183+{
3184+ if (!m_nmIface->isValid())
3185+ return false;
3186+
3187+ return m_nmIface->property("State").toUInt() == 70;
3188+}
3189+
3190+QString Status::networkIcon()
3191+{
3192+ QString iconName = QStringLiteral("nm-no-connection");
3193+
3194+ if (!online()) {
3195+ return iconName;
3196+ }
3197+
3198+ const QString primaryConn = m_nmIface->property("PrimaryConnection").value<QDBusObjectPath>().path();
3199+ const QString primaryConnType = m_nmIface->property("PrimaryConnectionType").toString();
3200+
3201+ if (primaryConn.isEmpty()) {
3202+ qWarning() << "Empty primary connection";
3203+ return iconName;
3204+ }
3205+
3206+ if (primaryConnType == "802-11-wireless") {
3207+ QDBusInterface activeConn("org.freedesktop.NetworkManager", primaryConn, "org.freedesktop.NetworkManager.Connection.Active", QDBusConnection::systemBus());
3208+
3209+ if (activeConn.isValid()) {
3210+ const QString apPath = activeConn.property("SpecificObject").value<QDBusObjectPath>().path();
3211+
3212+ if (apPath.isEmpty()) {
3213+ qWarning() << "No AP path";
3214+ return iconName;
3215+ }
3216+
3217+ QDBusConnection::systemBus().connect("org.freedesktop.NetworkManager", primaryConn, "org.freedesktop.NetworkManager.Connection.Active", "PropertiesChanged",
3218+ this, SLOT(onNMPropertiesChanged(QVariantMap)));
3219+
3220+ QDBusInterface ap("org.freedesktop.NetworkManager", apPath, "org.freedesktop.NetworkManager.AccessPoint", QDBusConnection::systemBus());
3221+
3222+ if (!ap.isValid()) {
3223+ qWarning() << "Invalid AP";
3224+ return iconName;
3225+ }
3226+
3227+ QDBusConnection::systemBus().connect("org.freedesktop.NetworkManager", apPath, "org.freedesktop.NetworkManager.AccessPoint", "PropertiesChanged",
3228+ this, SLOT(onNMPropertiesChanged(QVariantMap)));
3229+
3230+ const uint strength = ap.property("Strength").toUInt();
3231+ const uint flags = ap.property("Flags").toUInt();
3232+
3233+ if (strength == 0) {
3234+ iconName = "nm-signal-00";
3235+ } else if (strength <= 25) {
3236+ iconName = "nm-signal-25";
3237+ } else if (strength <= 50) {
3238+ iconName = "nm-signal-50";
3239+ } else if (strength <= 75) {
3240+ iconName = "nm-signal-75";
3241+ } else if (strength <= 100) {
3242+ iconName = "nm-signal-100";
3243+ }
3244+
3245+ if (flags >= 1) {
3246+ iconName += "-secure";
3247+ }
3248+ }
3249+ }
3250+
3251+ return iconName;
3252+}
3253+
3254+void Status::initUPower()
3255+{
3256+ m_upowerIface = new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower/devices/DisplayDevice", "org.freedesktop.UPower.Device",
3257+ QDBusConnection::systemBus(), this);
3258+ QDBusConnection::systemBus().connect("org.freedesktop.UPower", "/org/freedesktop/UPower/devices/DisplayDevice", "org.freedesktop.DBus.Properties",
3259+ "PropertiesChanged", this, SLOT(onUPowerPropertiesChanged(QString,QVariantMap,QStringList)));
3260+}
3261+
3262+void Status::onUPowerPropertiesChanged(const QString &iface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
3263+{
3264+ Q_UNUSED(iface)
3265+ Q_UNUSED(invalidatedProps)
3266+
3267+ if (changedProps.contains("IconName")) {
3268+ Q_EMIT batteryIconChanged();
3269+ }
3270+}
3271+
3272+QString Status::batteryIcon() const
3273+{
3274+ const QString iconName = m_upowerIface->property("IconName").toString();
3275+ return iconName;
3276+}
3277
3278=== added file 'plugins/Wizard/Status.h'
3279--- plugins/Wizard/Status.h 1970-01-01 00:00:00 +0000
3280+++ plugins/Wizard/Status.h 2016-03-11 18:12:46 +0000
3281@@ -0,0 +1,60 @@
3282+/*
3283+ * Copyright (C) 2015 Canonical Ltd.
3284+ *
3285+ * This program is free software: you can redistribute it and/or modify it
3286+ * under the terms of the GNU General Public License version 3, as published
3287+ * by the Free Software Foundation.
3288+ *
3289+ * This program is distributed in the hope that it will be useful, but
3290+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3291+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
3292+ * PURPOSE. See the GNU General Public License for more details.
3293+ *
3294+ * You should have received a copy of the GNU General Public License along
3295+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3296+ */
3297+
3298+#ifndef WIZARD_STATUS_H
3299+#define WIZARD_STATUS_H
3300+
3301+#include <QObject>
3302+#include <QString>
3303+#include <QDBusInterface>
3304+
3305+class Status: public QObject
3306+{
3307+ Q_OBJECT
3308+ Q_PROPERTY(bool online READ online NOTIFY onlineChanged)
3309+ Q_PROPERTY(QString networkIcon READ networkIcon NOTIFY networkIconChanged)
3310+ Q_PROPERTY(QString batteryIcon READ batteryIcon NOTIFY batteryIconChanged)
3311+public:
3312+ Status();
3313+ ~Status() = default;
3314+
3315+ bool online() const;
3316+ QString networkIcon();
3317+
3318+ QString batteryIcon() const;
3319+
3320+Q_SIGNALS:
3321+ void networkIconChanged();
3322+ void onlineChanged();
3323+ void batteryIconChanged();
3324+
3325+private Q_SLOTS:
3326+ void onNMPropertiesChanged(const QVariantMap &changedProps);
3327+ void onUPowerPropertiesChanged(const QString &iface, const QVariantMap &changedProps, const QStringList &invalidatedProps);
3328+
3329+private:
3330+ Q_DISABLE_COPY(Status)
3331+
3332+ // network status
3333+ void initNM();
3334+ QDBusInterface * m_nmIface = nullptr;
3335+
3336+ // battery status
3337+ void initUPower();
3338+ QDBusInterface * m_upowerIface = nullptr;
3339+};
3340+
3341+#endif
3342
3343=== modified file 'plugins/Wizard/System.cpp'
3344--- plugins/Wizard/System.cpp 2015-09-23 15:14:01 +0000
3345+++ plugins/Wizard/System.cpp 2016-03-11 18:12:46 +0000
3346@@ -1,5 +1,5 @@
3347 /*
3348- * Copyright (C) 2014 Canonical Ltd.
3349+ * Copyright (C) 2014-2015 Canonical Ltd.
3350 *
3351 * This program is free software: you can redistribute it and/or modify it
3352 * under the terms of the GNU General Public License version 3, as published
3353@@ -25,10 +25,10 @@
3354 #include <QLocale>
3355 #include <QMap>
3356 #include <QProcess>
3357+#include <QDebug>
3358
3359 System::System()
3360- : QObject(),
3361- m_fsWatcher()
3362+ : QObject()
3363 {
3364 // Register the argument needed for UpdateActivationEnvironment below
3365 qDBusRegisterMetaType<QMap<QString,QString>>();
3366@@ -88,7 +88,7 @@
3367 QDBusConnection::sessionBus().asyncCall(msg);
3368 }
3369
3370-void System::updateSessionLanguage(const QString &locale)
3371+void System::updateSessionLocale(const QString &locale)
3372 {
3373 const QString language = locale.split(QStringLiteral("."))[0];
3374
3375@@ -106,5 +106,6 @@
3376 initctl stop smart-scopes-proxy; \
3377 initctl emit --no-wait indicator-services-start; \
3378 initctl restart --no-wait maliit-server; \
3379+ initctl restart --no-wait indicator-messages; \
3380 initctl restart --no-wait unity8-dash\""));
3381 }
3382
3383=== modified file 'plugins/Wizard/System.h'
3384--- plugins/Wizard/System.h 2015-05-21 16:05:57 +0000
3385+++ plugins/Wizard/System.h 2016-03-11 18:12:46 +0000
3386@@ -1,5 +1,5 @@
3387 /*
3388- * Copyright (C) 2014 Canonical Ltd.
3389+ * Copyright (C) 2014-2015 Canonical Ltd.
3390 *
3391 * This program is free software: you can redistribute it and/or modify it
3392 * under the terms of the GNU General Public License version 3, as published
3393@@ -28,12 +28,13 @@
3394
3395 public:
3396 System();
3397+ ~System() = default;
3398
3399 bool wizardEnabled() const;
3400 void setWizardEnabled(bool enabled);
3401
3402 public Q_SLOTS:
3403- void updateSessionLanguage(const QString &locale);
3404+ void updateSessionLocale(const QString &locale);
3405
3406 Q_SIGNALS:
3407 void wizardEnabledChanged();
3408
3409=== modified file 'plugins/Wizard/plugin.cpp'
3410--- plugins/Wizard/plugin.cpp 2014-11-21 19:28:16 +0000
3411+++ plugins/Wizard/plugin.cpp 2016-03-11 18:12:46 +0000
3412@@ -17,19 +17,18 @@
3413 #include "plugin.h"
3414 #include "PageList.h"
3415 #include "System.h"
3416+#include "timezonemodel.h"
3417+#include "LocalePlugin.h"
3418+#include "Status.h"
3419
3420 #include <QtQml/qqml.h>
3421
3422-static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3423-{
3424- Q_UNUSED(engine)
3425- Q_UNUSED(scriptEngine)
3426- return new System();
3427-}
3428-
3429 void WizardPlugin::registerTypes(const char *uri)
3430 {
3431 Q_ASSERT(uri == QLatin1String("Wizard"));
3432 qmlRegisterType<PageList>(uri, 0, 1, "PageList");
3433- qmlRegisterSingletonType<System>(uri, 0, 1, "System", system_provider);
3434+ qmlRegisterSingletonType<System>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new System; });
3435+ qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });
3436+ qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");
3437+ qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");
3438 }
3439
3440=== modified file 'plugins/Wizard/plugin.h'
3441--- plugins/Wizard/plugin.h 2015-04-30 09:31:51 +0000
3442+++ plugins/Wizard/plugin.h 2016-03-11 18:12:46 +0000
3443@@ -17,13 +17,12 @@
3444 #ifndef WIZARD_PLUGIN_H
3445 #define WIZARD_PLUGIN_H
3446
3447-#include <QtQml/QQmlEngine>
3448 #include <QtQml/QQmlExtensionPlugin>
3449
3450 class WizardPlugin : public QQmlExtensionPlugin
3451 {
3452 Q_OBJECT
3453- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
3454+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
3455
3456 public:
3457 void registerTypes(const char *uri) override;
3458
3459=== added file 'plugins/Wizard/timezonemodel.cpp'
3460--- plugins/Wizard/timezonemodel.cpp 1970-01-01 00:00:00 +0000
3461+++ plugins/Wizard/timezonemodel.cpp 2016-03-11 18:12:46 +0000
3462@@ -0,0 +1,239 @@
3463+/*
3464+ * Copyright (C) 2016 Canonical Ltd.
3465+ *
3466+ * This program is free software: you can redistribute it and/or modify it
3467+ * under the terms of the GNU General Public License version 3, as published
3468+ * by the Free Software Foundation.
3469+ *
3470+ * This program is distributed in the hope that it will be useful, but
3471+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3472+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
3473+ * PURPOSE. See the GNU General Public License for more details.
3474+ *
3475+ * You should have received a copy of the GNU General Public License along
3476+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3477+ */
3478+
3479+#include <QDebug>
3480+
3481+#include <glib.h>
3482+#include <glib-object.h>
3483+
3484+#include "LocalePlugin.h"
3485+#include "timezonemodel.h"
3486+
3487+TimeZoneLocationModel::TimeZoneLocationModel(QObject *parent):
3488+ QAbstractListModel(parent),
3489+ m_listUpdating(false),
3490+ m_cancellable(nullptr)
3491+{
3492+ m_roleNames[Qt::DisplayRole] = "displayName";
3493+ m_roleNames[TimeZoneRole] = "timeZone";
3494+ m_roleNames[CityRole] = "city";
3495+ m_roleNames[CountryRole] = "country";
3496+ m_roleNames[OffsetRole] = "offset";
3497+ m_roleNames[LatitudeRole] = "latitude";
3498+ m_roleNames[LongitudeRole] = "longitude";
3499+}
3500+
3501+int TimeZoneLocationModel::rowCount(const QModelIndex &parent) const
3502+{
3503+ if (parent.isValid()) {
3504+ return 0;
3505+ } else if (m_filter.isEmpty()) {
3506+ return m_countryLocations.count();
3507+ } else {
3508+ return m_locations.count();
3509+ }
3510+}
3511+
3512+QVariant TimeZoneLocationModel::data(const QModelIndex &index, int role) const
3513+{
3514+ GeonamesCity *city;
3515+ if (m_filter.isEmpty()) {
3516+ city = m_countryLocations.value(index.row());
3517+ } else {
3518+ city = m_locations.value(index.row());
3519+ }
3520+ if (!city)
3521+ return QVariant();
3522+
3523+ switch (role) {
3524+ case Qt::DisplayRole:
3525+ return QStringLiteral("%1, %2, %3").arg(geonames_city_get_name(city))
3526+ .arg(geonames_city_get_state(city))
3527+ .arg(geonames_city_get_country(city));
3528+ case SimpleRole:
3529+ return QStringLiteral("%1, %2").arg(geonames_city_get_name(city))
3530+ .arg(geonames_city_get_country(city));
3531+ case TimeZoneRole:
3532+ return geonames_city_get_timezone(city);
3533+ case CountryRole:
3534+ return geonames_city_get_country(city);
3535+ case CityRole:
3536+ return geonames_city_get_name(city);
3537+ case OffsetRole: {
3538+ QTimeZone tmp(geonames_city_get_timezone(city));
3539+ return static_cast<double>(tmp.standardTimeOffset(QDateTime::currentDateTime())) / 3600;
3540+ }
3541+ case LatitudeRole:
3542+ return geonames_city_get_latitude(city);
3543+ case LongitudeRole:
3544+ return geonames_city_get_longitude(city);
3545+ default:
3546+ qWarning() << Q_FUNC_INFO << "Unknown role";
3547+ return QVariant();
3548+ }
3549+}
3550+
3551+QHash<int, QByteArray> TimeZoneLocationModel::roleNames() const
3552+{
3553+ return m_roleNames;
3554+}
3555+
3556+void TimeZoneLocationModel::setModel(const QList<GeonamesCity *> &locations)
3557+{
3558+ beginResetModel();
3559+
3560+ Q_FOREACH(GeonamesCity *city, m_locations) {
3561+ geonames_city_free(city);
3562+ }
3563+
3564+ m_locations = locations;
3565+ endResetModel();
3566+}
3567+
3568+void TimeZoneLocationModel::filterFinished(GObject *source_object,
3569+ GAsyncResult *res,
3570+ gpointer user_data)
3571+{
3572+ Q_UNUSED(source_object);
3573+
3574+ g_autofree gint *cities = nullptr;
3575+ guint cities_len = 0;
3576+ g_autoptr(GError) error = nullptr;
3577+
3578+ cities = geonames_query_cities_finish(res, &cities_len, &error);
3579+ if (error) {
3580+ if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
3581+ TimeZoneLocationModel *model = static_cast<TimeZoneLocationModel *>(user_data);
3582+ g_clear_object(&model->m_cancellable);
3583+ model->setListUpdating(false);
3584+ qWarning() << "Could not filter timezones:" << error->message;
3585+ }
3586+ return;
3587+ }
3588+
3589+ QList<GeonamesCity *> locations;
3590+
3591+ for (guint i = 0; i < cities_len; ++i) {
3592+ GeonamesCity *city = geonames_get_city(cities[i]);
3593+ if (city) {
3594+ locations.append(city);
3595+ }
3596+ }
3597+
3598+ TimeZoneLocationModel *model = static_cast<TimeZoneLocationModel *>(user_data);
3599+
3600+ g_clear_object(&model->m_cancellable);
3601+
3602+ model->setModel(locations);
3603+ model->setListUpdating(false);
3604+}
3605+
3606+bool TimeZoneLocationModel::listUpdating() const
3607+{
3608+ return m_listUpdating;
3609+}
3610+
3611+void TimeZoneLocationModel::setListUpdating(bool listUpdating)
3612+{
3613+ if (m_listUpdating != listUpdating) {
3614+ m_listUpdating = listUpdating;
3615+ Q_EMIT listUpdatingChanged();
3616+ }
3617+}
3618+
3619+QString TimeZoneLocationModel::filter() const
3620+{
3621+ return m_filter;
3622+}
3623+
3624+void TimeZoneLocationModel::setFilter(const QString &filter)
3625+{
3626+ if (filter != m_filter) {
3627+ m_filter = filter;
3628+ Q_EMIT filterChanged();
3629+ }
3630+
3631+ setListUpdating(true);
3632+
3633+ if (m_cancellable) {
3634+ g_cancellable_cancel(m_cancellable);
3635+ g_clear_object(&m_cancellable);
3636+ }
3637+
3638+ setModel(QList<GeonamesCity *>());
3639+
3640+ if (filter.isEmpty()) {
3641+ setListUpdating(false);
3642+ return;
3643+ }
3644+
3645+ m_cancellable = g_cancellable_new();
3646+ geonames_query_cities(filter.toUtf8().data(),
3647+ GEONAMES_QUERY_DEFAULT,
3648+ m_cancellable,
3649+ filterFinished,
3650+ this);
3651+}
3652+
3653+QString TimeZoneLocationModel::country() const
3654+{
3655+ return m_country;
3656+}
3657+
3658+static bool citycmp(GeonamesCity *a, GeonamesCity *b)
3659+{
3660+ return geonames_city_get_population(b) < geonames_city_get_population(a);
3661+}
3662+
3663+void TimeZoneLocationModel::setCountry(const QString &country)
3664+{
3665+ if (m_country == country)
3666+ return;
3667+
3668+ m_country = country;
3669+
3670+ Q_FOREACH(GeonamesCity *city, m_countryLocations) {
3671+ geonames_city_free(city);
3672+ }
3673+
3674+ gint num_cities = geonames_get_n_cities();
3675+ for (gint i = 0; i < num_cities; i++) {
3676+ GeonamesCity *city = geonames_get_city(i);
3677+ if (city && m_country == geonames_city_get_country_code(city)) {
3678+ m_countryLocations.append(city);
3679+ }
3680+ }
3681+
3682+ std::sort(m_countryLocations.begin(), m_countryLocations.end(), citycmp);
3683+
3684+ Q_EMIT countryChanged(country);
3685+}
3686+
3687+TimeZoneLocationModel::~TimeZoneLocationModel()
3688+{
3689+ if (m_cancellable) {
3690+ g_cancellable_cancel(m_cancellable);
3691+ g_clear_object(&m_cancellable);
3692+ }
3693+
3694+ Q_FOREACH(GeonamesCity *city, m_countryLocations) {
3695+ geonames_city_free(city);
3696+ }
3697+
3698+ Q_FOREACH(GeonamesCity *city, m_locations) {
3699+ geonames_city_free(city);
3700+ }
3701+}
3702
3703=== added file 'plugins/Wizard/timezonemodel.h'
3704--- plugins/Wizard/timezonemodel.h 1970-01-01 00:00:00 +0000
3705+++ plugins/Wizard/timezonemodel.h 2016-03-11 18:12:46 +0000
3706@@ -0,0 +1,80 @@
3707+/*
3708+ * Copyright (C) 2016 Canonical Ltd.
3709+ *
3710+ * This program is free software: you can redistribute it and/or modify it
3711+ * under the terms of the GNU General Public License version 3, as published
3712+ * by the Free Software Foundation.
3713+ *
3714+ * This program is distributed in the hope that it will be useful, but
3715+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3716+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
3717+ * PURPOSE. See the GNU General Public License for more details.
3718+ *
3719+ * You should have received a copy of the GNU General Public License along
3720+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3721+ */
3722+
3723+#ifndef TIMEZONEMODEL_H
3724+#define TIMEZONEMODEL_H
3725+
3726+#include <geonames.h>
3727+#include <glib.h>
3728+#include <QAbstractListModel>
3729+
3730+class TimeZoneLocationModel: public QAbstractListModel
3731+{
3732+ Q_OBJECT
3733+ Q_PROPERTY(bool listUpdating READ listUpdating NOTIFY listUpdatingChanged)
3734+ Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
3735+ Q_PROPERTY(QString country READ country WRITE setCountry NOTIFY countryChanged)
3736+ Q_ENUMS(Roles)
3737+
3738+public:
3739+ explicit TimeZoneLocationModel(QObject *parent = nullptr);
3740+ ~TimeZoneLocationModel();
3741+
3742+ enum Roles {
3743+ TimeZoneRole = Qt::UserRole + 1,
3744+ CityRole,
3745+ CountryRole,
3746+ SimpleRole,
3747+ OffsetRole,
3748+ LatitudeRole,
3749+ LongitudeRole
3750+ };
3751+
3752+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
3753+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
3754+ QHash<int, QByteArray> roleNames() const override;
3755+
3756+ bool listUpdating() const;
3757+
3758+ QString filter() const;
3759+ void setFilter(const QString &filter);
3760+
3761+ QString country() const;
3762+ void setCountry(const QString &country);
3763+
3764+Q_SIGNALS:
3765+ void listUpdatingChanged();
3766+ void filterChanged();
3767+ void countryChanged(const QString &country);
3768+
3769+private:
3770+ void setModel(const QList<GeonamesCity *> &locations);
3771+ void setListUpdating(bool listUpdating);
3772+ static void filterFinished(GObject *source_object,
3773+ GAsyncResult *res,
3774+ gpointer user_data);
3775+
3776+
3777+ bool m_listUpdating;
3778+ QString m_filter;
3779+ QString m_country;
3780+ GCancellable *m_cancellable;
3781+ QHash<int, QByteArray> m_roleNames;
3782+ QList<GeonamesCity *> m_locations;
3783+ QList<GeonamesCity *> m_countryLocations;
3784+};
3785+
3786+#endif
3787
3788=== modified file 'po/unity8.pot'
3789--- po/unity8.pot 2016-03-08 21:04:17 +0000
3790+++ po/unity8.pot 2016-03-11 18:12:46 +0000
3791@@ -8,7 +8,7 @@
3792 msgstr ""
3793 "Project-Id-Version: unity8\n"
3794 "Report-Msgid-Bugs-To: \n"
3795-"POT-Creation-Date: 2016-03-08 21:04+0000\n"
3796+"POT-Creation-Date: 2016-03-10 22:48+0000\n"
3797 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
3798 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
3799 "Language-Team: LANGUAGE <LL@li.org>\n"
3800@@ -22,16 +22,16 @@
3801 msgid "Password: "
3802 msgstr ""
3803
3804-#: plugins/Unity/Launcher/launcheritem.cpp:47
3805-#: plugins/Unity/Launcher/launcheritem.cpp:106
3806+#: plugins/Unity/Launcher/launcheritem.cpp:48
3807+#: plugins/Unity/Launcher/launcheritem.cpp:107
3808 msgid "Pin shortcut"
3809 msgstr ""
3810
3811-#: plugins/Unity/Launcher/launcheritem.cpp:52
3812+#: plugins/Unity/Launcher/launcheritem.cpp:53
3813 msgid "Quit"
3814 msgstr ""
3815
3816-#: plugins/Unity/Launcher/launcheritem.cpp:106
3817+#: plugins/Unity/Launcher/launcheritem.cpp:107
3818 msgid "Unpin shortcut"
3819 msgstr ""
3820
3821@@ -135,15 +135,15 @@
3822 msgid "Restart"
3823 msgstr ""
3824
3825-#: qml/Components/Lockscreen.qml:245
3826+#: qml/Components/Lockscreen.qml:231
3827 msgid "Return to Call"
3828 msgstr ""
3829
3830-#: qml/Components/Lockscreen.qml:245
3831+#: qml/Components/Lockscreen.qml:231
3832 msgid "Emergency Call"
3833 msgstr ""
3834
3835-#: qml/Components/Lockscreen.qml:277
3836+#: qml/Components/Lockscreen.qml:263
3837 msgid "OK"
3838 msgstr ""
3839
3840@@ -152,6 +152,8 @@
3841 msgstr ""
3842
3843 #: qml/Components/ModeSwitchWarningDialog.qml:57
3844+msgctxt ""
3845+"Re-dock means connect the device again to an external screen/mouse/keyboard"
3846 msgid "Re-dock, save your work and close these apps to continue."
3847 msgstr ""
3848
3849@@ -194,15 +196,15 @@
3850 msgid "Add to Favorites"
3851 msgstr ""
3852
3853-#: qml/Dash/GenericScopeView.qml:565 qml/Dash/GenericScopeView.qml:723
3854+#: qml/Dash/GenericScopeView.qml:567 qml/Dash/GenericScopeView.qml:725
3855 msgid "See less"
3856 msgstr ""
3857
3858-#: qml/Dash/GenericScopeView.qml:565
3859+#: qml/Dash/GenericScopeView.qml:567
3860 msgid "See all"
3861 msgstr ""
3862
3863-#: qml/Dash/GenericScopeView.qml:627
3864+#: qml/Dash/GenericScopeView.qml:629
3865 msgctxt "Label: Hint for dash search line edit"
3866 msgid "Search"
3867 msgstr ""
3868@@ -228,7 +230,7 @@
3869 msgid "Add a review"
3870 msgstr ""
3871
3872-#: qml/Dash/Previews/PreviewSharing.qml:50
3873+#: qml/Dash/Previews/PreviewSharing.qml:66
3874 msgid "Preview Share Item"
3875 msgstr ""
3876
3877@@ -256,13 +258,13 @@
3878 msgid "Also installed"
3879 msgstr ""
3880
3881-#: qml/DisabledScreenNotice.qml:87
3882+#: qml/DisabledScreenNotice.qml:104
3883 msgid ""
3884 "Your device is now connected to an external display. Use this screen as a "
3885-"touch pad to interact with the mouse."
3886+"touch pad to interact with the pointer."
3887 msgstr ""
3888
3889-#: qml/Greeter/CoverPage.qml:107
3890+#: qml/Greeter/CoverPage.qml:118
3891 msgid "Unlock"
3892 msgstr ""
3893
3894@@ -341,62 +343,62 @@
3895 msgid "Conference"
3896 msgstr ""
3897
3898-#: qml/Panel/Indicators/MenuItemFactory.qml:753
3899+#: qml/Panel/Indicators/MenuItemFactory.qml:752
3900 msgid "Nothing is playing"
3901 msgstr ""
3902
3903-#: qml/Panel/Indicators/MenuItemFactory.qml:882
3904+#: qml/Panel/Indicators/MenuItemFactory.qml:881
3905 #, qt-format
3906 msgid "%1 hour"
3907 msgid_plural "%1 hours"
3908 msgstr[0] ""
3909 msgstr[1] ""
3910
3911-#: qml/Panel/Indicators/MenuItemFactory.qml:886
3912+#: qml/Panel/Indicators/MenuItemFactory.qml:885
3913 #, qt-format
3914 msgid "%1 minute"
3915 msgid_plural "%1 minutes"
3916 msgstr[0] ""
3917 msgstr[1] ""
3918
3919-#: qml/Panel/Indicators/MenuItemFactory.qml:891
3920+#: qml/Panel/Indicators/MenuItemFactory.qml:890
3921 #, qt-format
3922 msgid "%1 second"
3923 msgid_plural "%1 seconds"
3924 msgstr[0] ""
3925 msgstr[1] ""
3926
3927-#: qml/Panel/Indicators/MenuItemFactory.qml:894
3928+#: qml/Panel/Indicators/MenuItemFactory.qml:893
3929 msgid "0 seconds"
3930 msgstr ""
3931
3932 #. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
3933-#: qml/Panel/Indicators/MenuItemFactory.qml:896
3934+#: qml/Panel/Indicators/MenuItemFactory.qml:895
3935 #, qt-format
3936 msgid "%1 remaining"
3937 msgstr ""
3938
3939-#: qml/Panel/Indicators/MenuItemFactory.qml:902
3940+#: qml/Panel/Indicators/MenuItemFactory.qml:901
3941 msgid "In queue…"
3942 msgstr ""
3943
3944-#: qml/Panel/Indicators/MenuItemFactory.qml:906
3945+#: qml/Panel/Indicators/MenuItemFactory.qml:905
3946 msgid "Downloading"
3947 msgstr ""
3948
3949-#: qml/Panel/Indicators/MenuItemFactory.qml:908
3950+#: qml/Panel/Indicators/MenuItemFactory.qml:907
3951 msgid "Paused, tap to resume"
3952 msgstr ""
3953
3954-#: qml/Panel/Indicators/MenuItemFactory.qml:910
3955+#: qml/Panel/Indicators/MenuItemFactory.qml:909
3956 msgid "Canceled"
3957 msgstr ""
3958
3959-#: qml/Panel/Indicators/MenuItemFactory.qml:912
3960+#: qml/Panel/Indicators/MenuItemFactory.qml:911
3961 msgid "Finished"
3962 msgstr ""
3963
3964-#: qml/Panel/Indicators/MenuItemFactory.qml:914
3965+#: qml/Panel/Indicators/MenuItemFactory.qml:913
3966 msgid "Failed, tap to retry"
3967 msgstr ""
3968
3969
3970=== modified file 'qml/Components/EdgeBarrier.qml'
3971--- qml/Components/EdgeBarrier.qml 2015-11-24 17:44:18 +0000
3972+++ qml/Components/EdgeBarrier.qml 2016-03-11 18:12:46 +0000
3973@@ -105,7 +105,7 @@
3974 },
3975 Transition {
3976 from: "resisting"; to: "passed"
3977- UbuntuNumberAnimation { target: materialContainer; property: "opacity" }
3978+ UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration; target: materialContainer; property: "opacity" }
3979 }
3980 ]
3981 }
3982
3983=== modified file 'qml/Components/Lockscreen.qml'
3984--- qml/Components/Lockscreen.qml 2015-07-15 15:07:19 +0000
3985+++ qml/Components/Lockscreen.qml 2016-03-11 18:12:46 +0000
3986@@ -121,107 +121,93 @@
3987 opacity: root.darkenBackground
3988 }
3989
3990- MouseArea {
3991- anchors.fill: root
3992- onClicked: {
3993- if (pinPadLoader.item)
3994- pinPadLoader.item.forceActiveFocus()
3995- }
3996- }
3997-
3998- FocusScope {
3999- id: loaderScope
4000+ Loader {
4001+ id: pinPadLoader
4002+ objectName: "pinPadLoader"
4003 anchors.fill: parent
4004-
4005- Loader {
4006- id: pinPadLoader
4007- objectName: "pinPadLoader"
4008- anchors.fill: parent
4009- property bool resetting: false
4010- property bool waiting: false
4011- property bool showWrongText: false
4012-
4013- source: {
4014- if (resetting || !root.required) {
4015- return ""
4016- } else if (root.delayMinutes > 0) {
4017- return "DelayedLockscreen.qml"
4018- } else if (root.alphaNumeric) {
4019- return "PassphraseLockscreen.qml"
4020- } else {
4021- return "PinLockscreen.qml"
4022- }
4023- }
4024- onSourceChanged: {
4025- waiting = false
4026- showWrongText = false
4027- if (loaderScope.activeFocus && pinPadLoader.item)
4028- pinPadLoader.item.forceActiveFocus()
4029- }
4030-
4031- Connections {
4032- target: pinPadLoader.item
4033-
4034- onEntered: {
4035- pinPadLoader.waiting = true
4036- root.entered(passphrase);
4037- }
4038-
4039- onCancel: {
4040- root.cancel()
4041- }
4042- }
4043-
4044- Binding {
4045- target: pinPadLoader.item
4046- property: "minPinLength"
4047- value: root.minPinLength
4048- }
4049- Binding {
4050- target: pinPadLoader.item
4051- property: "maxPinLength"
4052- value: root.maxPinLength
4053- }
4054- Binding {
4055- target: pinPadLoader.item
4056- property: "infoText"
4057- value: root.infoText
4058- }
4059- Binding {
4060- target: pinPadLoader.item
4061- property: "retryText"
4062- value: root.retryText
4063- }
4064- Binding {
4065- target: pinPadLoader.item
4066- property: "errorText"
4067- value: pinPadLoader.showWrongText ? root.errorText : ""
4068- }
4069- Binding {
4070- target: pinPadLoader.item
4071- property: "entryEnabled"
4072- value: !pinPadLoader.waiting
4073- }
4074- Binding {
4075- target: pinPadLoader.item
4076- property: "alphaNumeric"
4077- value: root.alphaNumeric
4078- }
4079- Binding {
4080- target: pinPadLoader.item
4081- property: "delayMinutes"
4082- value: root.delayMinutes
4083- }
4084- Binding {
4085- target: pinPadLoader.item
4086- property: "showCancelButton"
4087- value: root.showCancelButton
4088- }
4089- Binding {
4090- target: pinPadLoader.item
4091- property: "foregroundColor"
4092- value: root.foregroundColor
4093- }
4094+ property bool resetting: false
4095+ property bool waiting: false
4096+ property bool showWrongText: false
4097+ focus: true
4098+
4099+ source: {
4100+ if (resetting || !root.required) {
4101+ return ""
4102+ } else if (root.delayMinutes > 0) {
4103+ return "DelayedLockscreen.qml"
4104+ } else if (root.alphaNumeric) {
4105+ return "PassphraseLockscreen.qml"
4106+ } else {
4107+ return "PinLockscreen.qml"
4108+ }
4109+ }
4110+ onSourceChanged: {
4111+ waiting = false
4112+ showWrongText = false
4113+ }
4114+
4115+ Connections {
4116+ target: pinPadLoader.item
4117+
4118+ onEntered: {
4119+ pinPadLoader.waiting = true
4120+ root.entered(passphrase);
4121+ }
4122+
4123+ onCancel: {
4124+ root.cancel()
4125+ }
4126+ }
4127+
4128+ Binding {
4129+ target: pinPadLoader.item
4130+ property: "minPinLength"
4131+ value: root.minPinLength
4132+ }
4133+ Binding {
4134+ target: pinPadLoader.item
4135+ property: "maxPinLength"
4136+ value: root.maxPinLength
4137+ }
4138+ Binding {
4139+ target: pinPadLoader.item
4140+ property: "infoText"
4141+ value: root.infoText
4142+ }
4143+ Binding {
4144+ target: pinPadLoader.item
4145+ property: "retryText"
4146+ value: root.retryText
4147+ }
4148+ Binding {
4149+ target: pinPadLoader.item
4150+ property: "errorText"
4151+ value: pinPadLoader.showWrongText ? root.errorText : ""
4152+ }
4153+ Binding {
4154+ target: pinPadLoader.item
4155+ property: "entryEnabled"
4156+ value: !pinPadLoader.waiting
4157+ }
4158+ Binding {
4159+ target: pinPadLoader.item
4160+ property: "alphaNumeric"
4161+ value: root.alphaNumeric
4162+ }
4163+ Binding {
4164+ target: pinPadLoader.item
4165+ property: "delayMinutes"
4166+ value: root.delayMinutes
4167+ }
4168+ Binding {
4169+ target: pinPadLoader.item
4170+ property: "showCancelButton"
4171+ value: root.showCancelButton
4172+ }
4173+ Binding {
4174+ target: pinPadLoader.item
4175+ property: "foregroundColor"
4176+ value: root.foregroundColor
4177 }
4178 }
4179
4180
4181=== modified file 'qml/Components/ModeSwitchWarningDialog.qml'
4182--- qml/Components/ModeSwitchWarningDialog.qml 2015-11-25 13:57:34 +0000
4183+++ qml/Components/ModeSwitchWarningDialog.qml 2016-03-11 18:12:46 +0000
4184@@ -54,7 +54,7 @@
4185 }
4186
4187 Label {
4188- text: i18n.tr("Re-dock, save your work and close these apps to continue.")
4189+ text: i18n.ctr("Re-dock means connect the device again to an external screen/mouse/keyboard", "Re-dock, save your work and close these apps to continue.")
4190 wrapMode: Text.WordWrap
4191 color: "#888888"
4192 }
4193
4194=== modified file 'qml/Components/PassphraseLockscreen.qml'
4195--- qml/Components/PassphraseLockscreen.qml 2015-07-15 15:07:19 +0000
4196+++ qml/Components/PassphraseLockscreen.qml 2016-03-11 18:12:46 +0000
4197@@ -18,10 +18,11 @@
4198 import Ubuntu.Components 1.3
4199 import "../Components"
4200
4201-Item {
4202+FocusScope {
4203 id: root
4204 y: units.gu(4)
4205 height: shakeContainer.height
4206+ focus: true
4207
4208 property string infoText
4209 property string errorText
4210@@ -42,8 +43,6 @@
4211 }
4212 }
4213
4214- onActiveFocusChanged: if (activeFocus) pinentryField.forceActiveFocus()
4215-
4216 Column {
4217 id: shakeContainer
4218 anchors.horizontalCenter: parent.horizontalCenter
4219@@ -59,14 +58,16 @@
4220 text: root.infoText
4221 }
4222
4223- Item {
4224+ FocusScope {
4225 id: entryContainer
4226 anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
4227 height: units.gu(4)
4228+ focus: true
4229
4230 TextInput {
4231 id: pinentryField
4232 objectName: "pinentryField"
4233+ focus: true
4234
4235 property bool incorrectOverride: false
4236
4237
4238=== modified file 'qml/Components/PhysicalKeysMapper.qml'
4239--- qml/Components/PhysicalKeysMapper.qml 2016-01-13 18:43:34 +0000
4240+++ qml/Components/PhysicalKeysMapper.qml 2016-03-11 18:12:46 +0000
4241@@ -42,12 +42,15 @@
4242 signal screenshotTriggered;
4243
4244 readonly property bool altTabPressed: d.altTabPressed
4245+ readonly property bool superPressed: d.superPressed
4246+ readonly property bool superTabPressed: d.superTabPressed
4247
4248 property int powerKeyLongPressTime: 2000
4249
4250 // For testing. If running windowed (e.g. tryShell), Alt+Tab is taken by the
4251 // running desktop, set this to true to use Ctrl+Tab instead.
4252 property bool controlInsteadOfAlt: false
4253+ property bool controlInsteadOfSuper: false
4254
4255 QtObject {
4256 id: d
4257@@ -59,6 +62,9 @@
4258 property bool altPressed: false
4259 property bool altTabPressed: false
4260
4261+ property bool superPressed: false
4262+ property bool superTabPressed: false
4263+
4264 property var powerButtonPressStart: 0
4265
4266 // We need to eat ALT presses until we know what they're for (Alt+Tab or going to the app?)
4267@@ -119,11 +125,23 @@
4268 event.accepted = true;
4269 d.altPressInjected = false;
4270 }
4271+
4272+ // Adding MetaModifier here because that's what keyboards do. Pressing Super_L actually gives
4273+ // Super_L + MetaModifier. This helps to make sure we only invoke superPressed if no other
4274+ // Modifier is pressed too.
4275+ } else if (((event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R) && event.modifiers === Qt.MetaModifier)
4276+ || (root.controlInsteadOfSuper && event.key == Qt.Key_Control)
4277+ ) {
4278+ d.superPressed = true;
4279 } else if (event.key == Qt.Key_Tab) {
4280 if (d.altPressed && !d.altTabPressed) {
4281 d.altTabPressed = true;
4282 event.accepted = true;
4283 }
4284+ if (d.superPressed && !d.superTabPressed) {
4285+ d.superTabPressed = true;
4286+ event.accepted = true;
4287+ }
4288 }
4289 }
4290
4291@@ -154,6 +172,12 @@
4292 if (d.altTabPressed) {
4293 event.accepted = true;
4294 }
4295+ } else if (event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R || (root.controlInsteadOfSuper && event.key == Qt.Key_Control)) {
4296+ d.superPressed = false;
4297+ if (d.superTabPressed) {
4298+ d.superTabPressed = false;
4299+ event.accepted = true;
4300+ }
4301 }
4302 }
4303 }
4304
4305=== modified file 'qml/Components/PinLockscreen.qml'
4306--- qml/Components/PinLockscreen.qml 2015-07-15 15:07:19 +0000
4307+++ qml/Components/PinLockscreen.qml 2016-03-11 18:12:46 +0000
4308@@ -19,8 +19,9 @@
4309 import Ubuntu.Components.ListItems 1.3
4310 import "../Components"
4311
4312-Item {
4313+FocusScope {
4314 id: root
4315+ focus: true
4316
4317 property string infoText
4318 property string retryText
4319@@ -45,6 +46,24 @@
4320 }
4321 }
4322
4323+ Keys.onPressed: {
4324+ if (pinentryField.text.length == root.maxPinLength)
4325+ return;
4326+
4327+ if (event.key === Qt.Key_Backspace) {
4328+ pinentryField.backspace();
4329+ } else if (event.key === Qt.Key_Delete || event.key === Qt.Key_Escape) {
4330+ closeButton.clicked()
4331+ } else if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
4332+ confirmButton.clicked()
4333+ } else {
4334+ var digit = parseInt(event.text);
4335+ if (!isNaN(digit) && typeof digit == "number") {
4336+ pinentryField.appendNumber(digit);
4337+ }
4338+ }
4339+ }
4340+
4341 Column {
4342 anchors {
4343 left: parent.left;
4344@@ -204,6 +223,7 @@
4345 width: numbersGrid.buttonWidth
4346 }
4347 PinPadButton {
4348+ id: closeButton
4349 iconName: "close"
4350 height: units.gu(5) // visual spec has this row a little closer in
4351 width: numbersGrid.buttonWidth
4352@@ -216,6 +236,7 @@
4353 width: numbersGrid.buttonWidth
4354 }
4355 PinPadButton {
4356+ id: confirmButton
4357 iconName: "tick"
4358 objectName: "confirmButton"
4359 height: units.gu(5)
4360
4361=== modified file 'qml/Components/ShellDialog.qml'
4362--- qml/Components/ShellDialog.qml 2015-11-06 10:06:58 +0000
4363+++ qml/Components/ShellDialog.qml 2016-03-11 18:12:46 +0000
4364@@ -37,7 +37,15 @@
4365
4366 focus: true
4367
4368+ // FIXME: this is a hack because Dialog subtheming seems broken atm
4369+ // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1555548
4370+ ThemeSettings {
4371+ id: themeHack
4372+ name: "Ubuntu.Components.Themes.Ambiance"
4373+ }
4374+
4375 Component.onCompleted: {
4376+ __foreground.theme = themeHack
4377 show();
4378 }
4379 }
4380
4381=== modified file 'qml/Dash/CardCarousel.qml'
4382--- qml/Dash/CardCarousel.qml 2016-01-28 14:11:14 +0000
4383+++ qml/Dash/CardCarousel.qml 2016-03-11 18:12:46 +0000
4384@@ -66,7 +66,6 @@
4385 item.cardData = Qt.binding(function() { return model; });
4386 item.fontScale = Qt.binding(function() { return carousel.fontScale; });
4387 item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
4388- item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
4389 item.artShapeStyle = "shadow";
4390 item.scopeStyle = cardCarousel.scopeStyle;
4391 }
4392
4393=== modified file 'qml/Dash/CardGrid.qml'
4394--- qml/Dash/CardGrid.qml 2016-02-02 08:47:07 +0000
4395+++ qml/Dash/CardGrid.qml 2016-03-11 18:12:46 +0000
4396@@ -70,7 +70,6 @@
4397 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
4398 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
4399 item.cardData = Qt.binding(function() { return model; });
4400- item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
4401 item.scopeStyle = root.scopeStyle;
4402 item.artShapeStyle = root.artShapeStyle;
4403 item.backgroundShapeStyle = root.backgroundShapeStyle;
4404
4405=== modified file 'qml/Dash/CardHorizontalList.qml'
4406--- qml/Dash/CardHorizontalList.qml 2016-01-28 14:11:14 +0000
4407+++ qml/Dash/CardHorizontalList.qml 2016-03-11 18:12:46 +0000
4408@@ -53,7 +53,6 @@
4409 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
4410 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
4411 item.cardData = Qt.binding(function() { return model; });
4412- item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
4413 item.scopeStyle = root.scopeStyle;
4414 }
4415 Connections {
4416
4417=== modified file 'qml/Dash/CardTool.qml'
4418--- qml/Dash/CardTool.qml 2016-01-28 14:11:14 +0000
4419+++ qml/Dash/CardTool.qml 2016-03-11 18:12:46 +0000
4420@@ -66,7 +66,7 @@
4421 return layout;
4422 }
4423
4424- property var cardComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components);
4425+ property var cardComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, false);
4426
4427 // FIXME: Saviq
4428 // Only way for the card below to actually be laid out completely.
4429@@ -139,29 +139,6 @@
4430 readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
4431 property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0
4432
4433- /*!
4434- \brief Desired alignment of title
4435- */
4436- readonly property int titleAlignment: {
4437- if (template["card-layout"] === "horizontal"
4438- || typeof components["title"] !== "object"
4439- || components["title"]["align"] === "left") return Text.AlignLeft;
4440-
4441- var keys = ["mascot", "emblem", "subtitle", "attributes", "summary"];
4442-
4443- for (var key in keys) {
4444- key = keys[key];
4445- try {
4446- if (typeof components[key] === "string"
4447- || typeof components[key]["field"] === "string") return Text.AlignLeft;
4448- } catch (e) {
4449- continue;
4450- }
4451- }
4452-
4453- return Text.AlignHCenter;
4454- }
4455-
4456 QtObject {
4457 id: carouselTool
4458
4459@@ -216,10 +193,9 @@
4460 "summary": "—\n—\n—\n—\n—",
4461 "attributes": attributesModel.model
4462 }
4463- sourceComponent: cardTool.cardComponent
4464+ sourceComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, true);
4465 onLoaded: {
4466 item.objectName = "cardToolCard";
4467- item.asynchronous = false;
4468 item.width = Qt.binding(function() { return cardTool.cardWidth !== -1 ? cardTool.cardWidth : item.implicitWidth; });
4469 item.height = Qt.binding(function() { return cardTool.cardHeight !== -1 ? cardTool.cardHeight : item.implicitHeight; });
4470 }
4471
4472=== modified file 'qml/Dash/CardVerticalJournal.qml'
4473--- qml/Dash/CardVerticalJournal.qml 2016-01-28 14:11:14 +0000
4474+++ qml/Dash/CardVerticalJournal.qml 2016-03-11 18:12:46 +0000
4475@@ -72,7 +72,6 @@
4476 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
4477 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
4478 item.cardData = Qt.binding(function() { return model; });
4479- item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
4480 item.scopeStyle = root.scopeStyle;
4481 }
4482 Connections {
4483
4484=== modified file 'qml/Dash/Dash.qml'
4485--- qml/Dash/Dash.qml 2015-11-19 16:55:31 +0000
4486+++ qml/Dash/Dash.qml 2016-03-11 18:12:46 +0000
4487@@ -37,6 +37,7 @@
4488 }
4489
4490 property bool windowActive: window.active
4491+ property bool showOverlayScope: false
4492
4493 DashCommunicatorService {
4494 objectName: "dashCommunicatorService"
4495@@ -80,7 +81,7 @@
4496 return
4497 }
4498
4499- closeOverlayScope();
4500+ dash.showOverlayScope = false;
4501
4502 dashContent.closePreview();
4503
4504@@ -93,12 +94,6 @@
4505 dashContent.setCurrentScopeAtIndex(scopeIndex, animate, reset)
4506 }
4507
4508- function closeOverlayScope() {
4509- if (dashContent.x != 0) {
4510- dashContent.x = 0;
4511- }
4512- }
4513-
4514 Scopes {
4515 id: scopes
4516 }
4517@@ -133,12 +128,13 @@
4518 height: dash.height
4519 scopes: scopes
4520 visible: x != -width
4521+ x: dash.showOverlayScope ? -width : 0
4522 onGotoScope: {
4523 dash.setCurrentScope(scopeId, true, false);
4524 }
4525 onOpenScope: {
4526 scopeItem.scope = scope;
4527- x = -width;
4528+ dash.showOverlayScope = true;
4529 }
4530 Behavior on x {
4531 UbuntuNumberAnimation {
4532@@ -207,7 +203,7 @@
4533 bottomEdgeController.enableAnimation = true;
4534 bottomEdgeController.progress = 0;
4535 scopeItem.scope = scope;
4536- dashContent.x = -dashContent.width;
4537+ dash.showOverlayScope = true;
4538 }
4539 onGotoScope: {
4540 bottomEdgeController.enableAnimation = true;
4541@@ -226,7 +222,7 @@
4542 id: scopeItem
4543 objectName: "dashTempScopeItem"
4544
4545- x: dashContent.x + width
4546+ x: dash.showOverlayScope ? 0 : width
4547 y: dashContent.y
4548 width: parent.width
4549 height: parent.height
4550@@ -234,7 +230,7 @@
4551 hasBackAction: true
4552 isCurrent: visible
4553 onBackClicked: {
4554- closeOverlayScope();
4555+ dash.showOverlayScope = false;
4556 closePreview();
4557 }
4558
4559@@ -250,6 +246,10 @@
4560 scopes.closeScope(oldScope);
4561 }
4562 }
4563+
4564+ Behavior on x {
4565+ UbuntuNumberAnimation { }
4566+ }
4567 }
4568
4569 Rectangle {
4570
4571=== modified file 'qml/Dash/GenericScopeView.qml'
4572--- qml/Dash/GenericScopeView.qml 2016-02-19 11:50:12 +0000
4573+++ qml/Dash/GenericScopeView.qml 2016-03-11 18:12:46 +0000
4574@@ -370,6 +370,8 @@
4575 } else {
4576 cardTool.cardWidth = units.gu(10);
4577 }
4578+ } else {
4579+ cardTool.cardWidth = units.gu(12);
4580 }
4581 item.minimumHorizontalSpacing = item.defaultMinimumHorizontalSpacing;
4582 }
4583
4584=== modified file 'qml/Dash/Previews/PreviewHeader.qml'
4585--- qml/Dash/Previews/PreviewHeader.qml 2016-01-08 14:19:08 +0000
4586+++ qml/Dash/Previews/PreviewHeader.qml 2016-03-11 18:12:46 +0000
4587@@ -25,6 +25,7 @@
4588 * The mascot fall back image comes in widgetData["fallback"]
4589 * The subtitle comes in widgetData["subtitle"]
4590 * The attributes comes in widgetData["attributes"]
4591+ * The emblem comes in widgetData["emblem"]
4592 */
4593
4594 PreviewWidget {
4595@@ -40,6 +41,7 @@
4596 readonly property string title: root.widgetData["title"] || ""
4597 readonly property string subtitle: root.widgetData["subtitle"] || ""
4598 readonly property var attributes: root.widgetData["attributes"] || null
4599+ readonly property url emblem: root.widgetData["emblem"] || ""
4600 readonly property color fontColor: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
4601
4602 // Rewire the source since we may have unwired it on onStatusChanged
4603@@ -98,16 +100,42 @@
4604 spacing: units.dp(2)
4605 anchors.verticalCenter: parent.verticalCenter
4606
4607- Label {
4608- id: titleLabel
4609- objectName: "titleLabel"
4610+ Item {
4611 anchors { left: parent.left; right: parent.right }
4612- elide: Text.ElideRight
4613- font.weight: Font.Normal
4614- fontSize: "large"
4615- wrapMode: Text.Wrap
4616- color: headerRoot.fontColor
4617- text: headerRoot.title
4618+ height: titleLabel.height
4619+
4620+ Label {
4621+ id: titleLabel
4622+ objectName: "titleLabel"
4623+ anchors {
4624+ left: parent.left;
4625+ right: iconLoader.right
4626+ rightMargin: iconLoader.width > 0 ? units.gu(0.5) : 0
4627+ }
4628+ elide: Text.ElideRight
4629+ font.weight: Font.Normal
4630+ fontSize: "large"
4631+ wrapMode: Text.Wrap
4632+ color: headerRoot.fontColor
4633+ text: headerRoot.title
4634+ }
4635+
4636+ Loader {
4637+ id: iconLoader
4638+ active: headerRoot.emblem != ""
4639+ anchors {
4640+ bottom: titleLabel.baseline
4641+ right: parent.right
4642+ }
4643+ sourceComponent: Icon {
4644+ objectName: "emblemIcon"
4645+ source: headerRoot.emblem
4646+ color: headerRoot.fontColor
4647+ height: source != "" ? titleLabel.font.pixelSize : 0
4648+ // FIXME Workaround for bug https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1421293
4649+ width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth
4650+ }
4651+ }
4652 }
4653
4654 Loader {
4655
4656=== modified file 'qml/Dash/Previews/PreviewOverlay.qml'
4657--- qml/Dash/Previews/PreviewOverlay.qml 2015-07-15 15:07:19 +0000
4658+++ qml/Dash/Previews/PreviewOverlay.qml 2016-03-11 18:12:46 +0000
4659@@ -158,7 +158,7 @@
4660 anchors.centerIn: parent
4661 width: units.gu(2.5)
4662 height: width
4663- color: theme.palette.normal.foregroundText
4664+ color: "white"
4665 name: "close"
4666 }
4667 }
4668
4669=== modified file 'qml/Dash/Previews/PreviewSharing.qml'
4670--- qml/Dash/Previews/PreviewSharing.qml 2015-12-17 15:42:39 +0000
4671+++ qml/Dash/Previews/PreviewSharing.qml 2016-03-11 18:12:46 +0000
4672@@ -44,6 +44,22 @@
4673 }
4674 }
4675
4676+ function createExportedItems(url) {
4677+ var items = new Array();
4678+ if (typeof url === "string") {
4679+ var exportItem = exportItemComponent.createObject();
4680+ exportItem.url = url;
4681+ items.push(exportItem);
4682+ } else {
4683+ for (var i = 0; i < url.length; i++) {
4684+ var exportItem = exportItemComponent.createObject();
4685+ exportItem.url = url[i];
4686+ items.push(exportItem);
4687+ }
4688+ }
4689+ return items;
4690+ }
4691+
4692 Component {
4693 id: exportItemComponent
4694 ContentItem {
4695@@ -76,13 +92,7 @@
4696 onPeerSelected: {
4697 var transfer = peer.request();
4698 if (transfer.state === ContentTransfer.InProgress) {
4699- var items = new Array();
4700- for (var i = 0; i < url.length; i++) {
4701- var exportItem = exportItemComponent.createObject();
4702- exportItem.url = url[i];
4703- items.push(exportItem);
4704- }
4705- transfer.items = items;
4706+ transfer.items = createExportedItems(url);
4707 transfer.state = ContentTransfer.Charged;
4708 }
4709 peerPicker.visible = false;
4710
4711=== modified file 'qml/Dash/ScopesListCategoryItem.qml'
4712--- qml/Dash/ScopesListCategoryItem.qml 2015-11-04 14:57:13 +0000
4713+++ qml/Dash/ScopesListCategoryItem.qml 2016-03-11 18:12:46 +0000
4714@@ -18,7 +18,7 @@
4715 import QtQuick.Layouts 1.1
4716 import Ubuntu.Components 1.3
4717
4718-MouseArea {
4719+AbstractButton {
4720 id: root
4721
4722 signal requestFavorite(string scopeId, bool favorite)
4723@@ -84,15 +84,19 @@
4724 visible: text != ""
4725 }
4726 }
4727- MouseArea {
4728+ AbstractButton {
4729 id: starArea
4730 objectName: "starArea"
4731 height: parent.height
4732 width: height
4733 anchors.right: parent.right
4734 onClicked: if (!editMode) root.requestFavorite(model.scopeId, !isFavorite);
4735- onPressed: if (editMode) root.handlePressed(starArea);
4736- onReleased: if (editMode) root.handleReleased(starArea);
4737+ onPressedChanged: {
4738+ if (editMode) {
4739+ if (pressed) root.handlePressed(starArea.__mouseArea);
4740+ else root.handleReleased(starArea.__mouseArea);
4741+ }
4742+ }
4743 visible: editMode || showStar
4744 Icon {
4745 id: star
4746
4747=== modified file 'qml/DeviceConfiguration.qml'
4748--- qml/DeviceConfiguration.qml 2015-12-01 13:56:54 +0000
4749+++ qml/DeviceConfiguration.qml 2016-03-11 18:12:46 +0000
4750@@ -1,5 +1,5 @@
4751 /*
4752- * Copyright (C) 2015 Canonical, Ltd.
4753+ * Copyright (C) 2015-2016 Canonical, Ltd.
4754 *
4755 * This program is free software; you can redistribute it and/or modify
4756 * it under the terms of the GNU General Public License as published by
4757@@ -15,6 +15,7 @@
4758 */
4759
4760 import QtQuick 2.4
4761+import Utils 0.1
4762
4763 QtObject {
4764 id: root
4765@@ -34,57 +35,83 @@
4766
4767 readonly property alias category: priv.category
4768
4769+ readonly property var deviceConfigParser: DeviceConfigParser {
4770+ name: root.name
4771+ }
4772+
4773 readonly property var priv: StateGroup {
4774 id: priv
4775
4776- property int primaryOrientation: root.useNativeOrientation
4777-
4778- property int supportedOrientations: Qt.PortraitOrientation
4779- | Qt.InvertedPortraitOrientation
4780- | Qt.LandscapeOrientation
4781- | Qt.InvertedLandscapeOrientation
4782-
4783- property int landscapeOrientation: Qt.LandscapeOrientation
4784- property int invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
4785- property int portraitOrientation: Qt.PortraitOrientation
4786- property int invertedPortraitOrientation: Qt.InvertedPortraitOrientation
4787-
4788- // Supported values so far:
4789- // "phone", "tablet" or "desktop"
4790- property string category: "phone"
4791+ property int primaryOrientation: deviceConfigParser.primaryOrientation == Qt.PrimaryOrientation ?
4792+ root.useNativeOrientation : deviceConfigParser.primaryOrientation
4793+
4794+ property int supportedOrientations: deviceConfigParser.supportedOrientations
4795+
4796+ property int landscapeOrientation: deviceConfigParser.landscapeOrientation
4797+ property int invertedLandscapeOrientation: deviceConfigParser.invertedLandscapeOrientation
4798+ property int portraitOrientation: deviceConfigParser.portraitOrientation
4799+ property int invertedPortraitOrientation: deviceConfigParser.invertedPortraitOrientation
4800+ property string category: deviceConfigParser.category
4801
4802 states: [
4803 State {
4804 name: "mako"
4805 PropertyChanges {
4806 target: priv
4807+ primaryOrientation: root.useNativeOrientation
4808 supportedOrientations: Qt.PortraitOrientation
4809 | Qt.LandscapeOrientation
4810 | Qt.InvertedLandscapeOrientation
4811+ landscapeOrientation: Qt.LandscapeOrientation
4812+ invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
4813+ portraitOrientation: Qt.PortraitOrientation
4814+ invertedPortraitOrientation: Qt.InvertedPortraitOrientation
4815+ category: "phone"
4816 }
4817 },
4818 State {
4819 name: "krillin"
4820 PropertyChanges {
4821 target: priv
4822+ primaryOrientation: root.useNativeOrientation
4823 supportedOrientations: Qt.PortraitOrientation
4824 | Qt.LandscapeOrientation
4825 | Qt.InvertedLandscapeOrientation
4826+ landscapeOrientation: Qt.LandscapeOrientation
4827+ invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
4828+ portraitOrientation: Qt.PortraitOrientation
4829+ invertedPortraitOrientation: Qt.InvertedPortraitOrientation
4830+ category: "phone"
4831 }
4832 },
4833 State {
4834 name: "arale"
4835 PropertyChanges {
4836 target: priv
4837+ primaryOrientation: root.useNativeOrientation
4838 supportedOrientations: Qt.PortraitOrientation
4839 | Qt.LandscapeOrientation
4840 | Qt.InvertedLandscapeOrientation
4841+ landscapeOrientation: Qt.LandscapeOrientation
4842+ invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
4843+ portraitOrientation: Qt.PortraitOrientation
4844+ invertedPortraitOrientation: Qt.InvertedPortraitOrientation
4845+ category: "phone"
4846 }
4847 },
4848 State {
4849 name: "manta"
4850 PropertyChanges {
4851 target: priv
4852+ primaryOrientation: root.useNativeOrientation
4853+ supportedOrientations: Qt.PortraitOrientation
4854+ | Qt.InvertedPortraitOrientation
4855+ | Qt.LandscapeOrientation
4856+ | Qt.InvertedLandscapeOrientation
4857+ landscapeOrientation: Qt.LandscapeOrientation
4858+ invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
4859+ portraitOrientation: Qt.PortraitOrientation
4860+ invertedPortraitOrientation: Qt.InvertedPortraitOrientation
4861 category: "tablet"
4862 }
4863 },
4864@@ -92,9 +119,15 @@
4865 name: "flo"
4866 PropertyChanges {
4867 target: priv
4868+ primaryOrientation: Qt.InvertedLandscapeOrientation
4869+ supportedOrientations: Qt.PortraitOrientation
4870+ | Qt.InvertedPortraitOrientation
4871+ | Qt.LandscapeOrientation
4872+ | Qt.InvertedLandscapeOrientation
4873 landscapeOrientation: Qt.InvertedLandscapeOrientation
4874 invertedLandscapeOrientation: Qt.LandscapeOrientation
4875- primaryOrientation: Qt.InvertedLandscapeOrientation
4876+ portraitOrientation: Qt.PortraitOrientation
4877+ invertedPortraitOrientation: Qt.InvertedPortraitOrientation
4878 category: "tablet"
4879 }
4880 },
4881@@ -102,8 +135,13 @@
4882 name: "desktop"
4883 PropertyChanges {
4884 target: priv
4885+ primaryOrientation: root.useNativeOrientation
4886+ supportedOrientations: root.useNativeOrientation
4887+ landscapeOrientation: Qt.LandscapeOrientation
4888+ invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
4889+ portraitOrientation: Qt.PortraitOrientation
4890+ invertedPortraitOrientation: Qt.InvertedPortraitOrientation
4891 category: "desktop"
4892- supportedOrientations: root.useNativeOrientation
4893 }
4894 }
4895 ]
4896
4897=== modified file 'qml/DisabledScreenNotice.qml'
4898--- qml/DisabledScreenNotice.qml 2016-01-26 15:29:54 +0000
4899+++ qml/DisabledScreenNotice.qml 2016-03-11 18:12:46 +0000
4900@@ -17,6 +17,7 @@
4901 import QtQuick 2.4
4902 import QtQuick.Layouts 1.1
4903 import Ubuntu.Components 1.3
4904+import Unity.Session 0.1
4905 import QtQuick.Window 2.2
4906 import "Components"
4907
4908@@ -25,19 +26,36 @@
4909
4910 property bool infoNoteDisplayed: true
4911
4912- WallpaperResolver {
4913- width: root.width
4914- id: wallpaperResolver
4915+ // For testing
4916+ property var screen: Screen
4917+ property var orientationLock: OrientationLock
4918+
4919+ DeviceConfiguration {
4920+ id: deviceConfiguration
4921+ name: applicationArguments.deviceName
4922 }
4923
4924 Item {
4925 id: contentContainer
4926+ objectName: "contentContainer"
4927 anchors.centerIn: parent
4928 height: rotation == 90 || rotation == 270 ? parent.width : parent.height
4929 width: rotation == 90 || rotation == 270 ? parent.height : parent.width
4930
4931+ property int savedOrientation: deviceConfiguration.primaryOrientation == deviceConfiguration.useNativeOrientation
4932+ ? (root.width > root.height ? Qt.LandscapeOrientation : Qt.PortraitOrientation)
4933+ : deviceConfiguration.primaryOrientation
4934+
4935 rotation: {
4936- switch (Screen.orientation) {
4937+ var usedOrientation = root.screen.orientation;
4938+
4939+ if (root.orientationLock.enabled) {
4940+ usedOrientation = savedOrientation;
4941+ }
4942+
4943+ savedOrientation = usedOrientation;
4944+
4945+ switch (usedOrientation) {
4946 case Qt.PortraitOrientation:
4947 return 0;
4948 case Qt.LandscapeOrientation:
4949@@ -47,6 +65,8 @@
4950 case Qt.InvertedLandscapeOrientation:
4951 return 90;
4952 }
4953+
4954+ return 0;
4955 }
4956 transformOrigin: Item.Center
4957
4958@@ -60,9 +80,9 @@
4959 }
4960 }
4961
4962- Image {
4963+ Rectangle {
4964 anchors.fill: parent
4965- source: wallpaperResolver.background
4966+ color: "#3b3b3b"
4967 }
4968
4969 Item {
4970@@ -74,22 +94,26 @@
4971 UbuntuNumberAnimation { }
4972 }
4973
4974- Rectangle {
4975- anchors.fill: parent
4976- color: "black"
4977- opacity: 0.4
4978- }
4979-
4980- Label {
4981- id: text
4982+ Column {
4983 anchors.centerIn: parent
4984 width: parent.width - units.gu(8)
4985- text: i18n.tr("Your device is now connected to an external display. Use this screen as a touch pad to interact with the mouse.")
4986- color: "white"
4987- horizontalAlignment: Text.AlignHCenter
4988- verticalAlignment: Text.AlignVCenter
4989- fontSize: "x-large"
4990- wrapMode: Text.Wrap
4991+ spacing: units.gu(4)
4992+
4993+ Label {
4994+ id: text
4995+ text: i18n.tr("Your device is now connected to an external display. Use this screen as a touch pad to interact with the pointer.")
4996+ color: "white"
4997+ width: parent.width
4998+ fontSize: "large"
4999+ wrapMode: Text.Wrap
5000+ }
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches