on xenial help sign in
Merge
commitbb1c1d824aec08005c42dbbe19f5612465bbc376 authorAlbert Astals Cid <albert.astals@canonical.com> dateFri 6 Nov 2015, 11:20 (11 years ago) parent5637c5dd527f6b
457 files changed+6491−2737
CMakeLists.txt+11−8 data/unity8.conf+10 debian/changelog+94 debian/control+14−11 debian/copyright+21 debian/unity8-private.install+1 debian/unity8.install+1 plugins/CMakeLists.txt+1 plugins/Cursor/3rd_party/CMakeLists.txt+1 plugins/Cursor/3rd_party/xcursor/CMakeLists.txt+15 plugins/Cursor/3rd_party/xcursor/xcursor.c+968 plugins/Cursor/3rd_party/xcursor/xcursor.h+65 plugins/Cursor/CMakeLists.txt+28 plugins/Cursor/Cursor.qml+28 plugins/Cursor/CursorImageProvider.cpp+191 plugins/Cursor/CursorImageProvider.h+76 plugins/Cursor/MousePointer.cpp+125 plugins/Cursor/MousePointer.h+59 plugins/Cursor/plugin.cpp+39 plugins/Cursor/plugin.h+33 plugins/Cursor/qmldir+3 plugins/Dash/CardAttributes.qml+3−3 plugins/Dash/CardCreator.js+26−52 plugins/Dash/CardCreatorCache.qml+1−1 plugins/Dash/CroppedImageMinimumSourceSize.qml+1−1 plugins/Dash/ScopeStyle.qml+2−2 plugins/Dash/abstractdashview.h−4 plugins/Dash/horizontaljournal.cpp−4 plugins/Dash/horizontaljournal.h−4 plugins/Dash/organicgrid.cpp−4 plugins/Dash/organicgrid.h−4 plugins/Dash/verticaljournal.cpp−4 plugins/Dash/verticaljournal.h−4 plugins/IntegratedLightDM/UsersModel.cpp+7−6 plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+2−1 plugins/ScreenGrabber/screengrabber.cpp+2−2 plugins/ScreenGrabber/screengrabber.h+1−1 plugins/Unity/CMakeLists.txt+1 plugins/Unity/Launcher/desktopfilehandler.cpp+3−2 plugins/Unity/Platform/CMakeLists.txt+9 plugins/Unity/Platform/platform.cpp+43 plugins/Unity/Platform/platform.h+58 plugins/Unity/Platform/plugin.cpp+27 plugins/Utils/relativetimeformatter.h → plugins/Unity/Platform/plugin.h+10−12 plugins/Unity/Platform/qmldir+2 plugins/Unity/Session/dbusunitysessionservice.cpp+2−1 plugins/Utils/CMakeLists.txt−2 plugins/Utils/plugin.cpp−5 plugins/Utils/relativetimeformatter.cpp−260 plugins/Utils/timeformatter.cpp−206 plugins/Utils/timeformatter.h−68 plugins/Utils/timezoneFormatter.cpp+1−1 plugins/Utils/windowkeysfilter.cpp+15−1 plugins/Utils/windowkeysfilter.h+7 plugins/Utils/windowstatestorage.cpp+61−22 plugins/Utils/windowstatestorage.h+13−1 po/ug.po+6−6 po/unity8.pot+53−49 po/wo.po+800 qml/Components/Background.qml+2−2 qml/Components/BaseCarouselDelegate.qml+2−2 qml/Components/Carousel.qml+2−2 qml/Components/Circle.qml+1−1 qml/Components/DelayedLockscreen.qml+2−2 qml/Components/Dialogs.qml+5−4 qml/Components/DragHandle.qml+2−2 qml/Components/DraggingArea.qml+2−2 qml/Components/EdgeDragEvaluator.qml+2−2 qml/Components/Header.qml+2−2 qml/Components/InputMethod.qml+2−2 qml/Components/LazyImage.qml+24−13 qml/Components/ListItems/Header.qml+2−2 qml/Components/ListItems/ThinDivider.qml+1−1 qml/Components/ListViewOSKScroller.qml+53 qml/Components/Lockscreen.qml+3−3 qml/Components/NotificationAudio.qml+42 qml/Components/Orientations.qml+57 qml/Components/PanelState/PanelState.qml+1−1 qml/Components/PassphraseLockscreen.qml+2−2 qml/Components/PhysicalKeysMapper.qml+14−21 qml/Components/PinLockscreen.qml+3−3 qml/Components/PinPadButton.qml+2−2 qml/Components/Rating.qml+2−2 qml/Components/RatingStyle.qml+2−2 qml/Components/ResponsiveGridView.qml+2−2 qml/Components/ResponsiveVerticalJournal.qml+2−2 qml/Components/ScreenGrabber.qml+6−5 qml/Components/ScrollCalculator.qml+2−2 qml/Components/SearchHistoryModel/SearchHistoryModel.qml+1−1 qml/Components/ShellDialog.qml+3−3 qml/Components/Showable.qml+1−1 qml/Components/StandardAnimation.qml+1−1 qml/Components/UbuntuShapeForItem.qml+2−2 qml/Components/Unity8Settings.qml+1−1 qml/Components/UnityInputInfo/UnityInputInfo.qml+2−2 qml/Components/WallpaperResolver.qml+63 qml/Components/WindowControlButtons.qml+5−2 qml/Components/WindowScreenshot.qml+1−1 qml/Components/WrongPasswordAnimation.qml+1−1 qml/Components/ZoomableImage.qml+2−2 qml/Dash/CardCarousel.qml+3−3 qml/Dash/CardGrid.qml+1−1 qml/Dash/CardHorizontalList.qml+2−2 qml/Dash/CardTool.qml+1−1 qml/Dash/CardVerticalJournal.qml+2−2 qml/Dash/Dash.qml+2−2 qml/Dash/DashApplication.qml+4−3 qml/Dash/DashBackground.qml+1−1 qml/Dash/DashCategoryBase.qml+2−2 qml/Dash/DashContent.qml+2−2 qml/Dash/DashContentTabBarStyle.qml+1−1 qml/Dash/DashNavigation.qml+4−4 qml/Dash/DashNavigationButton.qml+4−4 qml/Dash/DashNavigationList.qml+5−5 qml/Dash/PageHeader.qml → qml/Dash/DashPageHeader.qml+12−16 qml/Dash/DashRenderer.qml+1−1 qml/Dash/GenericScopeView.qml+6−6 qml/Dash/PreviewListView.qml+3−3 qml/Dash/Previews/Preview.qml+13−20 qml/Dash/Previews/PreviewActionButton.qml+2−2 qml/Dash/Previews/PreviewActionCombo.qml+4−4 qml/Dash/Previews/PreviewActions.qml+4−4 qml/Dash/Previews/PreviewAudioPlayback.qml+7−7 qml/Dash/Previews/PreviewComment.qml+2−2 qml/Dash/Previews/PreviewCommentInput.qml+2−2 qml/Dash/Previews/PreviewExpandable.qml+5−5 qml/Dash/Previews/PreviewHeader.qml+10−10 qml/Dash/Previews/PreviewIconActions.qml+2−2 qml/Dash/Previews/PreviewImageGallery.qml+3−3 qml/Dash/Previews/PreviewMediaToolbar.qml+36 qml/Dash/Previews/PreviewOverlay.qml+4−4 qml/Dash/Previews/PreviewPayments.qml+2−2 qml/Dash/Previews/PreviewProgress.qml+2−2 qml/Dash/Previews/PreviewRatingDisplay.qml+4−4 qml/Dash/Previews/PreviewRatingEdit.qml+2−2 qml/Dash/Previews/PreviewRatingInput.qml+6−6 qml/Dash/Previews/PreviewRatingSingleDisplay.qml+1−1 qml/Dash/Previews/PreviewSharing.qml+105 qml/Dash/Previews/PreviewTable.qml+5−5 qml/Dash/Previews/PreviewTextSummary.qml+5−5 qml/Dash/Previews/PreviewVideoPlayback.qml+15−2 qml/Dash/Previews/PreviewWidget.qml+4−1 qml/Dash/Previews/PreviewWidgetFactory.qml+4−1 qml/Dash/Previews/PreviewZoomableImage.qml+21−9 qml/Dash/PullToRefreshScopeStyle.qml+3−3 qml/Dash/ScopeListView.qml+1−1 qml/Dash/ScopeSettings/ScopeSetting.qml+11−2 qml/Dash/ScopeSettings/ScopeSettingBoolean.qml+5−5 qml/Dash/ScopeSettings/ScopeSettingList.qml+3−3 qml/Dash/ScopeSettings/ScopeSettingNumber.qml+1−1 qml/Dash/ScopeSettings/ScopeSettingString.qml+12−6 qml/Dash/ScopeSettings/ScopeSettingsWidgetFactory.qml+5−1 qml/Dash/ScopeSettingsPage.qml+12−3 qml/Dash/ScopesList.qml+2−2 qml/Dash/ScopesListCategory.qml+4−4 qml/Dash/ScopesListCategoryItem.qml+4−4 qml/DeviceConfiguration.qml+87−64 qml/DisabledScreenNotice.qml+49 qml/Greeter/Clock.qml+2−2 qml/Greeter/CoverPage.qml+2−2 qml/Greeter/Dot.qml+1−1 qml/Greeter/Greeter.qml+3−3 qml/Greeter/Infographics.qml+2−2 qml/Greeter/IntegratedLightDMImpl.qml+1−1 qml/Greeter/LightDM.qml+1−1 qml/Greeter/LoginList.qml+2−2 qml/Greeter/NarrowView.qml+2−2 qml/Greeter/ObjectPositioner.qml+2−2 qml/Greeter/ShimGreeter.qml+1−1 qml/Greeter/WideView.qml+2−2 qml/Launcher/FoldingLauncherDelegate.qml+2−2 qml/Launcher/Launcher.qml+3−2 qml/Launcher/LauncherDelegate.qml+7−8 qml/Launcher/LauncherPanel.qml+6−6 qml/Notifications/Notification.qml+16−15 qml/Notifications/NotificationMenuItemFactory.qml+4−3 qml/Notifications/Notifications.qml+4−2 qml/Notifications/OptionToggle.qml+7−7 qml/Notifications/ShapedIcon.qml+3−3 qml/Notifications/SwipeToAct.qml+10−10 qml/OrientedShell.qml+44−25 qml/Panel/ActiveCallHint.qml+2−2 qml/Panel/Handle.qml+2−2 qml/Panel/IndicatorItem.qml+2−2 qml/Panel/IndicatorItemRow.qml+2−2 qml/Panel/IndicatorPage.qml+2−2 qml/Panel/Indicators/IndicatorBase.qml+1−1 qml/Panel/Indicators/IndicatorDelegate.qml+1−1 qml/Panel/Indicators/IndicatorsLight.qml+1−1 qml/Panel/Indicators/MenuItemFactory.qml+24−20 qml/Panel/Indicators/MessageMenuItemFactory.qml+36−27 qml/Panel/Indicators/ModemInfoItem.qml+6−6 qml/Panel/Indicators/RoamingIndication.qml+4−4 qml/Panel/Indicators/client/IndicatorRepresentation.qml+3−3 qml/Panel/Indicators/client/IndicatorsClient.qml+4−4 qml/Panel/Indicators/client/IndicatorsList.qml+3−3 qml/Panel/Indicators/client/IndicatorsTree.qml+2−2 qml/Panel/IndicatorsBar.qml+2−2 qml/Panel/IndicatorsMenu.qml+2−2 qml/Panel/MenuContent.qml+2−2 qml/Panel/Panel.qml+8−5 qml/Panel/PanelBackground.qml+1−1 qml/Panel/PanelSeparatorLine.qml+1−1 qml/Panel/PanelVelocityCalculator.qml+1−1 qml/Rotation/HalfLoopRotationAnimation.qml+1−1 qml/Rotation/ImmediateRotationAction.qml+1−1 qml/Rotation/NinetyRotationAnimation.qml+1−1 qml/Rotation/RotationStates.qml+4−4 qml/ScopeTool.qml+3−3 qml/Shell.qml+38−58 qml/Stages/AbstractStage.qml+63 qml/Stages/Animations/BaseSessionAnimation.qml+1−1 qml/Stages/Animations/SwipeFromBottomAnimation.qml+2−2 qml/Stages/ApplicationWindow.qml+4−2 qml/Stages/DecoratedWindow.qml+9−6 qml/Stages/DesktopSpread.qml+1−1 qml/Stages/DesktopSpreadDelegate.qml+2−2 qml/Stages/DesktopStage.qml+98−40 qml/Stages/MainViewStyle.qml+35−27 qml/Stages/OrientationChangeAnimation.qml+1−1 qml/Stages/PageHeadStyle.qml−76 qml/Stages/PhoneStage.qml+38−40 qml/Stages/SessionContainer.qml+1−1 qml/Stages/ShimStage.qml+3−3 qml/Stages/Splash.qml+25−30 qml/Stages/SpreadDelegate.qml+11−12 qml/Stages/SpreadMaths.qml+2−2 qml/Stages/SurfaceContainer.qml+3−2 qml/Stages/TabletStage.qml+43−39 qml/Stages/TransformedSpreadDelegate.qml+2−2 qml/Stages/TransformedTabletSpreadDelegate.qml+4−2 qml/Stages/WindowDecoration.qml+34−6 qml/Stages/WindowMoveResizeArea.qml−109 qml/Stages/WindowResizeArea.qml+215 qml/Stages/graphics/background_paper@27.png qml/Tutorial/Arrow.qml+2−2 qml/Tutorial/Slider.qml+2−2 qml/Tutorial/Tick.qml+2−2 qml/Tutorial/Tutorial.qml+2−2 qml/Tutorial/TutorialBottom.qml+2−2 qml/Tutorial/TutorialBottomFinish.qml+2−2 qml/Tutorial/TutorialContent.qml+2−2 qml/Tutorial/TutorialLeft.qml+2−2 qml/Tutorial/TutorialLeftFinish.qml+2−2 qml/Tutorial/TutorialPage.qml+2−2 qml/Tutorial/TutorialRight.qml+2−2 qml/Wizard/CheckableSetting.qml+5−5 qml/Wizard/Page.qml+4−4 qml/Wizard/Pages.qml+2−2 qml/Wizard/Pages/10-welcome.qml+3−3 qml/Wizard/Pages/20-sim.qml+2−2 qml/Wizard/Pages/30-passwd-type.qml+7−7 qml/Wizard/Pages/40-wifi.qml+3−3 qml/Wizard/Pages/50-location.qml+4−4 qml/Wizard/Pages/60-reporting.qml+2−2 qml/Wizard/Pages/80-finished.qml+2−2 qml/Wizard/Pages/here-terms.qml+4−4 qml/Wizard/Pages/passwd-confirm.qml+2−2 qml/Wizard/Pages/passwd-set.qml+2−2 qml/Wizard/StackButton.qml+4−4 qml/Wizard/Wizard.qml+2−2 qml/graphics/applicationIcons/libreoffice@18.png src/ApplicationArguments.h+10−2 src/CMakeLists.txt+3 src/SecondaryWindow.cpp+31 src/SecondaryWindow.h+30 src/ShellApplication.cpp+197 src/ShellApplication.h+55 src/ShellView.cpp+59 src/ShellView.h+34 src/main.cpp+4−101 tests/CMakeLists.txt+1 tests/autopilot/unity8/dash.py+3−3 tests/autopilot/unity8/fixture_setup.py+1−1 tests/autopilot/unity8/greeter/tests/__init__.py+1−1 tests/autopilot/unity8/launcher.py+1−1 tests/autopilot/unity8/process_helpers.py+1−1 tests/autopilot/unity8/settings_wizard/__init__.py+7−2 tests/autopilot/unity8/settings_wizard/tests/test_settings_wizard.py+10−5 tests/autopilot/unity8/shell/__init__.py+1−1 tests/autopilot/unity8/shell/tests/__init__.py+1−1 tests/imports/CMakeLists.txt+5 tests/imports/check_imports.py+125 tests/mocks/CMakeLists.txt+1 tests/mocks/Cursor/CMakeLists.txt+1 tests/mocks/Cursor/Cursor.qml+20 tests/mocks/Cursor/qmldir+2 tests/mocks/GSettings.1.0/fake_gsettings.cpp+31 tests/mocks/GSettings.1.0/fake_gsettings.h+10 tests/mocks/MeeGo/QOfono/MockOfonoSimManager.qml+1−1 tests/mocks/QMenuModel/QDBusActionGroup.qml+2−2 tests/mocks/QMenuModel/UnityMenuAction.qml+1−1 tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockLanguagePlugin.qml+1−1 tests/mocks/Ubuntu/Web/WebView.qml+1−1 tests/mocks/Unity/Application/ApplicationInfo.cpp+12 tests/mocks/Unity/Application/ApplicationInfo.h+4 tests/mocks/Unity/Application/ApplicationManager.cpp+9 tests/mocks/Unity/Application/ApplicationManager.h+1−1 tests/mocks/Unity/Application/MirSurface.cpp+41−14 tests/mocks/Unity/Application/MirSurface.h+14−4 tests/mocks/Unity/Application/MirSurfaceItem.cpp+12−2 tests/mocks/Unity/Application/MirSurfaceItem.h+1 tests/mocks/Unity/Application/resources/MirSurfaceItem.qml+1−1 tests/mocks/Unity/Application/resources/VirtualKeyboard.qml+1−1 tests/mocks/Unity/Indicators/ActionRootState.qml+1−1 tests/mocks/Unity/Indicators/IndicatorsModel.qml+1−1 tests/mocks/Unity/Indicators/ModelActionRootState.qml+1−1 tests/mocks/Unity/Launcher/MockQuickListModel.cpp+1−1 tests/mocks/Unity/fake_resultsmodel.cpp+1−1 tests/mocks/Unity/fake_scopesoverview.cpp+1−1 tests/mocks/Utils/CMakeLists.txt−2 tests/mocks/Utils/HomeKeyWatcher.qml+1−1 tests/mocks/Utils/Utils.qmltypes+31−28 tests/mocks/Utils/plugin.cpp−13 tests/mocks/Utils/windowstatestorage.cpp+17 tests/mocks/Utils/windowstatestorage.h+12 tests/plugins/Dash/cardcreator/1.res+7−8 tests/plugins/Dash/cardcreator/2.res+9−8 tests/plugins/Dash/cardcreator/3.res+8−9 tests/plugins/Dash/cardcreator/4.res+3−3 tests/plugins/Dash/cardcreator/5.res+18−45 tests/plugins/Dash/cardcreator/6.res+10−9 tests/plugins/Dash/cardcreator/7.res+10−9 tests/plugins/Dash/cardcreator/8.res+7−6 tests/plugins/Dash/cardcreatortest.qml+1−1 tests/plugins/Dash/horizontaljournaltest.qml+1−1 tests/plugins/Dash/horizontaljournaltry.qml+1−1 tests/plugins/Dash/listviewwithpageheadertest.qml+1−1 tests/plugins/Dash/listviewwithpageheadertestsection.qml+1−1 tests/plugins/Dash/listviewwithpageheadertestsectionexternalmodel.qml+1−1 tests/plugins/Dash/organicgridtest.qml+1−1 tests/plugins/Dash/organicgridtry.qml+1−1 tests/plugins/Dash/tst_CardAttributes.qml+1−1 tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qml+2−2 tests/plugins/Dash/tst_ListViewWithPageHeaderQML.qml+1−1 tests/plugins/Dash/tst_ScopeStyle.qml+2−2 tests/plugins/Dash/verticaljournaltest.qml+1−1 tests/plugins/Dash/verticaljournaltry.qml+1−1 tests/plugins/IntegratedLightDM/greeter.qml+1−1 tests/plugins/ScreenGrabber/ScreenGrabberTest.cpp+11 tests/plugins/ScreenGrabber/grabber.qml+1−1 tests/plugins/Ubuntu/Gestures/DownwardsLauncher.qml+2−2 tests/plugins/Ubuntu/Gestures/LeftwardsLauncher.qml+2−2 tests/plugins/Ubuntu/Gestures/RightwardsLauncher.qml+2−2 tests/plugins/Ubuntu/Gestures/UpwardsLauncher.qml+2−2 tests/plugins/Ubuntu/Gestures/empty.qml+1−1 tests/plugins/Ubuntu/Gestures/touchGateExample.qml+1−1 tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.qml+2−2 tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.qml+2−2 tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.qml+2−2 tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+1−5 tests/plugins/Unity/Indicators/UnityMenuModelStackTest.cpp+2−9 tests/plugins/Unity/Launcher/launchermodeltest.cpp+1 tests/plugins/Utils/CMakeLists.txt−1 tests/plugins/Utils/TimeFormatterTest.cpp−155 tests/plugins/Utils/tst_UtilsStyle.qml+1−1 tests/plugins/Wizard/tst_pagelist.cpp+5−5 tests/qmltests/CMakeLists.txt+5−2 tests/qmltests/Components/tst_Background.qml+1−1 tests/qmltests/Components/tst_Carousel.qml+1−1 tests/qmltests/Components/tst_Dialogs.qml+3−3 tests/qmltests/Components/tst_DragHandle.qml+2−2 tests/qmltests/Components/tst_DragHandle/BidirectionalShowable.qml+2−2 tests/qmltests/Components/tst_DragHandle/HorizontalShowable.qml+2−2 tests/qmltests/Components/tst_DragHandle/VerticalShowable.qml+2−2 tests/qmltests/Components/tst_DraggingArea.qml+1−1 tests/qmltests/Components/tst_EdgeDragEvaluator.qml+1−1 tests/qmltests/Components/tst_LazyImage.qml+4−4 tests/qmltests/Components/tst_LazyImage/ImageControls.qml+2−2 tests/qmltests/Components/tst_Lockscreen.qml+2−2 tests/qmltests/Components/tst_PhysicalKeysMapper.qml+11−10 tests/qmltests/Components/tst_Rating.qml+4−4 tests/qmltests/Components/tst_ResponsiveGridView.qml+3−3 tests/qmltests/Components/tst_ResponsiveVerticalJournal.qml+3−3 tests/qmltests/Components/tst_Showable.qml+2−2 tests/qmltests/Components/tst_WallpaperResolver.qml+89 tests/qmltests/Components/tst_ZoomableImage.qml+1−1 tests/qmltests/Dash/Previews/MockPreviewWidget.qml+1−1 tests/qmltests/Dash/Previews/tst_Preview.qml+3−3 tests/qmltests/Dash/Previews/tst_PreviewActions.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+4−4 tests/qmltests/Dash/Previews/tst_PreviewComment.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewCommentInput.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewExpandable.qml+6−6 tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewIconActions.qml+3−3 tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+1−1 tests/qmltests/Dash/Previews/tst_PreviewPayments.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewProgress.qml+2−2 tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml+4−4 tests/qmltests/Dash/Previews/tst_PreviewRatingEdit.qml+4−4 tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml+4−4 tests/qmltests/Dash/Previews/tst_PreviewSharing.qml+71 tests/qmltests/Dash/Previews/tst_PreviewTable.qml+4−4 tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+4−4 tests/qmltests/Dash/Previews/tst_PreviewVideoPlayback.qml+1−1 tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+3−3 tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+2−2 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml+2−2 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingList.qml+2−2 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml+2−2 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml+2−2 tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingsWidgetFactory.qml+2−2 tests/qmltests/Dash/tst_Card.qml+7−7 tests/qmltests/Dash/tst_CardBenchmark.qml+2−2 tests/qmltests/Dash/tst_CardTool.qml+2−2 tests/qmltests/Dash/tst_Dash.qml+3−3 tests/qmltests/Dash/tst_DashContent.qml+6−6 tests/qmltests/Dash/tst_PageHeader.qml → tests/qmltests/Dash/tst_DashPageHeader.qml+5−5 tests/qmltests/Dash/tst_GenericScopeView.qml+5−5 tests/qmltests/Dash/tst_PreviewListView.qml+5−5 tests/qmltests/Greeter/TestView.qml+2−2 tests/qmltests/Greeter/tst_Clock.qml+2−2 tests/qmltests/Greeter/tst_Greeter.qml+2−2 tests/qmltests/Greeter/tst_Infographics.qml+2−2 tests/qmltests/Greeter/tst_NarrowView.qml+2−2 tests/qmltests/Greeter/tst_WideView.qml+2−2 tests/qmltests/Launcher/tst_Launcher.qml+2−2 tests/qmltests/Notifications/tst_Notifications.qml+1−1 tests/qmltests/Notifications/tst_OptionToggle.qml+2−3 tests/qmltests/Notifications/tst_SwipeToAct.qml+1−1 tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml+2−2 tests/qmltests/Panel/IndicatorTest.qml+2−2 tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml+2−2 tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+7−17 tests/qmltests/Panel/Indicators/tst_MessageMenuItemFactory.qml+7−14 tests/qmltests/Panel/tst_ActiveCallHint.qml+1−1 tests/qmltests/Panel/tst_IndicatorItem.qml+2−2 tests/qmltests/Panel/tst_IndicatorItemRow.qml+2−2 tests/qmltests/Panel/tst_IndicatorPage.qml+1−1 tests/qmltests/Panel/tst_IndicatorsBar.qml+2−2 tests/qmltests/Panel/tst_IndicatorsMenu.qml+2−2 tests/qmltests/Panel/tst_MenuContent.qml+1−1 tests/qmltests/Panel/tst_Panel.qml+2−2 tests/qmltests/Stages/ApplicationCheckBox.qml+2−2 tests/qmltests/Stages/RecursingChildSessionControl.qml+2−2 tests/qmltests/Stages/tst_ApplicationWindow.qml+3−3 tests/qmltests/Stages/tst_DesktopStage.qml+84−8 tests/qmltests/Stages/tst_PhoneStage.qml+6−4 tests/qmltests/Stages/tst_SessionContainer.qml+2−2 tests/qmltests/Stages/tst_Splash.qml+2−2 tests/qmltests/Stages/tst_SpreadDelegate.qml+9−5 tests/qmltests/Stages/tst_SurfaceContainer.qml+2−2 tests/qmltests/Stages/tst_TabletStage.qml+10−5 tests/qmltests/Stages/tst_WindowMoveResizeArea.qml → tests/qmltests/Stages/tst_WindowResizeArea.qml+56−66 tests/qmltests/Tutorial/tst_Tutorial.qml+2−2 tests/qmltests/Wizard/tst_Wizard.qml+3−3 tests/qmltests/tst_DisabledScreenNotice.qml+37 tests/qmltests/tst_OrientedShell.qml+59−5 tests/qmltests/tst_Shell.qml+152−30 tests/qmltests/tst_ShellWithPin.qml+2−2 tests/qmltests/utils/Unity/Test/MockObjectForInstanceOfTest.qml+1−1 tests/qmltests/utils/Unity/Test/MockObjectForInstanceOfTestChild.qml+1−1 tests/qmltests/utils/Unity/Test/tst_UnityTest.qml+1−1 tests/utils/modules/Unity/Test/MouseTouchEmulationCheckbox.qml+2−2 tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp−2 tests/utils/modules/Unity/Test/UnityTestCase.qml+2−2
CMakeLists.txt+11−8
@@ -49,15 +49,15 @@ add_custom_target(cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2
4949 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
5050
5151include(FindPkgConfig)
52−find_package(Qt5Core 5.2 REQUIRED)
53−find_package(Qt5Qml 5.2 REQUIRED)
54−find_package(Qt5Quick 5.2 REQUIRED)
55−find_package(Qt5Gui 5.2 REQUIRED)
56−find_package(Qt5DBus 5.2 REQUIRED)
57−find_package(Qt5Concurrent 5.2 REQUIRED)
58−find_package(Qt5Sql 5.2 REQUIRED)
52+find_package(Qt5Core 5.4 REQUIRED)
53+find_package(Qt5Qml 5.4 REQUIRED)
54+find_package(Qt5Quick 5.4 REQUIRED)
55+find_package(Qt5Gui 5.4 REQUIRED)
56+find_package(Qt5DBus 5.4 REQUIRED)
57+find_package(Qt5Concurrent 5.4 REQUIRED)
58+find_package(Qt5Sql 5.4 REQUIRED)
5959
60−pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application>=8)
60+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=10)
6161
6262# Standard install paths
6363include(GNUInstallDirs)
@@ -101,6 +101,9 @@ add_definitions(-DQT_NO_KEYWORDS)
101101# Save a few container detach and conversions
102102add_definitions(-DQT_STRICT_ITERATORS)
103103
104+# Use the fast string builder
105+add_definitions(-DQT_USE_QSTRINGBUILDER)
106+
104107# Autopilot tests
105108include(autopilot)
106109declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
data/unity8.conf+10
@@ -46,6 +46,16 @@ pre-start script
4646 initctl set-env --global MIR_SERVER_PROMPT_FILE=1
4747
4848 initctl emit --no-wait indicator-services-start
49+
50+ # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
51+ # issues (LP: #1486341). As a bonus, this eliminates most of the
52+ # lag seen in the indicator panel pull-down (LP: #1488327) and also
53+ # reduces lag seen in apps:
54+ initctl set-env --global QML_NO_TOUCH_COMPRESSION=1
55+
56+ # For twice the fun and half the latency, try this (Warning: not all
57+ # devices are fast enough to keep up smoothly yet)...
58+ # initctl set-env MIR_SERVER_NBUFFERS=2
4959end script
5060
5161exec ${BINARY:-unity8} $ARGS
debian/changelog+94
@@ -1,3 +1,97 @@
1+unity8 (8.11+16.04.20151104-0ubuntu1) xenial; urgency=medium
2+
3+ [ Albert Astals Cid ]
4+ * Add an Item that proxies for old and new audio roles (LP: #1493851)
5+ * CroppedImageMinimumSourceSize: Fix 'Binding loop detected for
6+ property "imageAspectRatio"'
7+ * Make the scope settings list scroll to text visible area (LP:
8+ #1499084)
9+ * Move to importing QtQuick 2.4 & friends
10+ * Use SDK 1.3 across all files (LP: #1503498, #1508363, #1449628)
11+
12+ [ Andrea Cimitan ]
13+ * Add sharing widget to zoomable image and video playback
14+ * Make zoomable and video playback widgets edge to edge
15+ * Updated all 1.3 UbuntuShape to use new APIs where possible
16+ * Use SDK 1.3 across all files (LP: #1503498, #1508363, #1449628)
17+
18+ [ CI Train Bot ]
19+ * Resync trunk.
20+
21+ [ Christopher Lee ]
22+ * Quick spelling fix in process control output.
23+
24+ [ Daniel d'Andrada ]
25+ * Enable support for overriding application orientations based on
26+ device type (LP: #1478637)
27+ * Use SDK 1.3 across all files (LP: #1503498, #1508363, #1449628)
28+ * Use SDK 1.3 across all files (LP: #1503498, #1508363, #1449628)
29+
30+ [ Josh Arenson ]
31+ * Enable support for overriding application orientations based on
32+ device type (LP: #1478637)
33+
34+ [ Michael Terry ]
35+ * Avoid showing the shutdown dialog when turning on the screen if your
36+ device is under heavy load. (LP: #1508563)
37+ * Handle lifecycle policy exceptions ourselves, instead of letting
38+ qtmir do it for us and allow non-Touch apps to opt-out of the Touch
39+ lifecycle.
40+
41+ [ Michael Zanetti ]
42+ * Fixes for the panel buttons (LP: #1510360, #1504269, #1431566,
43+ #1443319)
44+ * Use SDK 1.3 across all files (LP: #1503498, #1508363, #1449628)
45+
46+ [ Michał Sawicz ]
47+ * Add missing copyright to Cursor.qml
48+ * Enable support for overriding application orientations based on
49+ device type (LP: #1478637)
50+ * Support server->client visibility change to stop rendering
51+ (lp:#1475678) (LP: #1475678)
52+
53+ [ Nick Dedekind ]
54+ * Support server->client visibility change to stop rendering
55+ (lp:#1475678) (LP: #1475678)
56+
57+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 04 Nov 2015 14:58:41 +0000
58+
59+unity8 (8.11+15.10.20151021-0ubuntu1) wily; urgency=medium
60+
61+ [ Albert Astals Cid ]
62+ * Clazy fixes
63+ * Enable Efficient String Construction by default
64+
65+ [ CI Train Bot ]
66+ * New rebuild forced.
67+
68+ [ Daniel d'Andrada ]
69+ * Have unity8 drawing its own cursor (LP: #1488417)
70+ * Initial multi-monitor support
71+
72+ [ Daniel van Vugt ]
73+ * Disable Qt's stuttering 'touch compression' to fix scrolling
74+ smoothness (LP: #1486341, #1488327)
75+
76+ [ Lukáš Tinkl ]
77+ * Fix autopilot wizard test skipping the reporting page
78+ * Implement Unity.Platform plugin wrapping org.freedesktop.hostname1
79+ (LP: #1504318)
80+ * React to window title (aka surface name) changes (LP: #1497092)
81+ * Rotate the screenshots according to the actual orientation
82+
83+ [ Michał Sawicz ]
84+ * Fix application API dependency
85+ * Have unity8 drawing its own cursor (LP: #1488417)
86+ * Initial multi-monitor support
87+ * Rotate the screenshots according to the actual orientation
88+
89+ [ Nick Dedekind ]
90+ * Fixed leak in UnityMenuModelStackTest
91+ * Moved time translation to SDK (LP: #1372061)
92+
93+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 21 Oct 2015 11:51:53 +0000
94+
195unity8 (8.11+15.10.20151009-0ubuntu1) wily; urgency=medium
296
397 [ CI Train Bot ]
debian/control+14−11
@@ -25,10 +25,11 @@ Build-Depends: cmake,
2525 libpay2-dev,
2626 libpulse-dev,
2727 libqmenumodel-dev (>= 0.2.9),
28+ libqt5svg5-dev,
2829 libqt5xmlpatterns5-dev,
2930 libsystemsettings-dev,
3031 libudev-dev,
31− libunity-api-dev (>= 7.100),
32+ libunity-api-dev (>= 7.102),
3233 libusermetricsoutput1-dev,
3334 libxcb1-dev,
3435 pkg-config,
@@ -41,15 +42,16 @@ Build-Depends: cmake,
4142 qml-module-qtsysteminfo,
4243 qml-module-qttest,
4344 qt5-default,
44− qtbase5-dev (>= 5.2.1),
45+ qtbase5-dev (>= 5.4),
4546 qtbase5-dev-tools,
46− qtbase5-private-dev (>= 5.2.1),
47− qtdeclarative5-dev (>= 5.2.1),
47+ qtbase5-private-dev (>= 5.4),
48+ qtdeclarative5-dev (>= 5.4),
4849 qtdeclarative5-dev-tools,
49− qtdeclarative5-private-dev (>= 5.2.1),
50+ qtdeclarative5-private-dev (>= 5.4),
5051 qtdeclarative5-qtmultimedia-plugin,
52+ qtdeclarative5-ubuntu-content1,
5153 qtdeclarative5-ubuntu-settings-components (>= 0.6),
52− qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.1.1239) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.1.1239),
54+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1676) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1676),
5355 qtdeclarative5-ubuntu-web-plugin,
5456 ttf-ubuntu-font-family,
5557Standards-Version: 3.9.4
@@ -64,7 +66,7 @@ X-Ubuntu-Use-Langpack: yes
6466Package: indicators-client
6567Architecture: amd64 armhf i386
6668Depends: qmenumodel-qml (>= 0.2.9),
67− qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.1.1239) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.1.1239),
69+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
6870 unity8 (= ${binary:Version}),
6971 ${misc:Depends},
7072 ${shlibs:Depends},
@@ -87,7 +89,8 @@ Description: Development tool for Unity scopes
8789Package: unity8
8890Architecture: any
8991Provides: indicator-renderer,
90−Depends: gsettings-desktop-schemas,
92+Depends: dmz-cursor-theme,
93+ gsettings-desktop-schemas,
9194 libcap2-bin,
9295 libglib2.0-bin,
9396 qmenumodel-qml (>= 0.2.9),
@@ -122,10 +125,10 @@ Architecture: all
122125Depends: qml-module-qtquick-layouts,
123126 qtdeclarative5-ubuntu-settings-components (>= 0.6),
124127 qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
125− qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.1.1239) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.1.1239),
128+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
126129 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
127130 ubuntu-thumbnailer-impl-0,
128− unity-application-impl-8,
131+ unity-application-impl-10,
129132 unity-notifications-impl-3,
130133 unity-plugin-scopes | unity-scopes-impl,
131134 unity-scopes-impl-7,
@@ -171,7 +174,7 @@ Pre-Depends: ${misc:Pre-Depends},
171174Depends: ${misc:Depends},
172175 ${shlibs:Depends},
173176Provides: unity-application-impl,
174− unity-application-impl-8,
177+ unity-application-impl-10,
175178Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
176179Description: Fake environment for running Unity 8 shell
177180 Provides fake implementations of some QML modules used by Unity 8 shell
debian/copyright+21
@@ -60,3 +60,24 @@ License: LGPL-2.1 with Digia Qt LGPL Exception 1.1 or GPL-3
6060 packaging of this file. Please review the following information to
6161 ensure the GNU General Public License version 3.0 requirements will be
6262 met: http://www.gnu.org/copyleft/gpl.html.
63+
64+Files: plugins/Cursor/3rd_party/xcursor/xcursor.*
65+Copyright: 2002 Keith Packard
66+License: Keith Packard
67+ Permission to use, copy, modify, distribute, and sell this software and its
68+ documentation for any purpose is hereby granted without fee, provided that
69+ the above copyright notice appear in all copies and that both that
70+ copyright notice and this permission notice appear in supporting
71+ documentation, and that the name of Keith Packard not be used in
72+ advertising or publicity pertaining to distribution of the software without
73+ specific, written prior permission. Keith Packard makes no
74+ representations about the suitability of this software for any purpose. It
75+ is provided "as is" without express or implied warranty.
76+ .
77+ KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
78+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
79+ EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
80+ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
81+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
82+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
83+ PERFORMANCE OF THIS SOFTWARE.
debian/unity8-private.install+1
@@ -1,6 +1,7 @@
11usr/lib/*/libunity8-private.*
22usr/lib/*/unity8/libUbuntuGestures*
33usr/lib/*/unity8/qml/AccountsService
4+usr/lib/*/unity8/qml/Cursor
45usr/lib/*/unity8/qml/Dash
56usr/lib/*/unity8/qml/GlobalShortcut
67usr/lib/*/unity8/qml/Greeter
debian/unity8.install+1
@@ -12,6 +12,7 @@ usr/share/unity8/Panel
1212usr/share/unity8/Rotation
1313usr/share/unity8/DeviceConfiguration.qml
1414usr/share/unity8/OrientedShell.qml
15+usr/share/unity8/DisabledScreenNotice.qml
1516usr/share/unity8/Shell.qml
1617usr/share/unity8/Stages
1718usr/share/unity8/Tutorial
plugins/CMakeLists.txt+1
@@ -12,6 +12,7 @@ macro(add_unity8_plugin PLUGIN VERSION PATH)
1212endmacro()
1313
1414add_subdirectory(AccountsService)
15+add_subdirectory(Cursor)
1516add_subdirectory(GlobalShortcut)
1617add_subdirectory(Greeter)
1718add_subdirectory(IntegratedLightDM)
plugins/Cursor/3rd_party/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(xcursor)
plugins/Cursor/3rd_party/xcursor/CMakeLists.txtnew file+15
@@ -0,0 +1,15 @@
1+add_definitions(-D_DEFAULT_SOURCE=1)
2+
3+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
4+
5+set(
6+ XCURSOR_SOURCES
7+
8+ xcursor.c
9+)
10+
11+add_library(
12+ xcursorloader-static STATIC
13+
14+ ${XCURSOR_SOURCES}
15+)
plugins/Cursor/3rd_party/xcursor/xcursor.cnew file+968
@@ -0,0 +1,968 @@
1+/*
2+ * Copyright © 2002 Keith Packard
3+ *
4+ * Permission to use, copy, modify, distribute, and sell this software and its
5+ * documentation for any purpose is hereby granted without fee, provided that
6+ * the above copyright notice appear in all copies and that both that
7+ * copyright notice and this permission notice appear in supporting
8+ * documentation, and that the name of Keith Packard not be used in
9+ * advertising or publicity pertaining to distribution of the software without
10+ * specific, written prior permission. Keith Packard makes no
11+ * representations about the suitability of this software for any purpose. It
12+ * is provided "as is" without express or implied warranty.
13+ *
14+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20+ * PERFORMANCE OF THIS SOFTWARE.
21+ */
22+
23+#include "xcursor.h"
24+#include <stdio.h>
25+#include <stdlib.h>
26+#include <string.h>
27+#include <dirent.h>
28+
29+/*
30+ * From libXcursor/include/X11/extensions/Xcursor.h
31+ */
32+
33+#define XcursorTrue 1
34+#define XcursorFalse 0
35+
36+/*
37+ * Cursor files start with a header. The header
38+ * contains a magic number, a version number and a
39+ * table of contents which has type and offset information
40+ * for the remaining tables in the file.
41+ *
42+ * File minor versions increment for compatible changes
43+ * File major versions increment for incompatible changes (never, we hope)
44+ *
45+ * Chunks of the same type are always upward compatible. Incompatible
46+ * changes are made with new chunk types; the old data can remain under
47+ * the old type. Upward compatible changes can add header data as the
48+ * header lengths are specified in the file.
49+ *
50+ * File:
51+ * FileHeader
52+ * LISTofChunk
53+ *
54+ * FileHeader:
55+ * CARD32 magic magic number
56+ * CARD32 header bytes in file header
57+ * CARD32 version file version
58+ * CARD32 ntoc number of toc entries
59+ * LISTofFileToc toc table of contents
60+ *
61+ * FileToc:
62+ * CARD32 type entry type
63+ * CARD32 subtype entry subtype (size for images)
64+ * CARD32 position absolute file position
65+ */
66+
67+#define XCURSOR_MAGIC 0x72756358 /* "Xcur" LSBFirst */
68+
69+/*
70+ * Current Xcursor version number. Will be substituted by configure
71+ * from the version in the libXcursor configure.ac file.
72+ */
73+
74+#define XCURSOR_LIB_MAJOR 1
75+#define XCURSOR_LIB_MINOR 1
76+#define XCURSOR_LIB_REVISION 13
77+#define XCURSOR_LIB_VERSION ((XCURSOR_LIB_MAJOR * 10000) + \
78+ (XCURSOR_LIB_MINOR * 100) + \
79+ (XCURSOR_LIB_REVISION))
80+
81+/*
82+ * This version number is stored in cursor files; changes to the
83+ * file format require updating this version number
84+ */
85+#define XCURSOR_FILE_MAJOR 1
86+#define XCURSOR_FILE_MINOR 0
87+#define XCURSOR_FILE_VERSION ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR))
88+#define XCURSOR_FILE_HEADER_LEN (4 * 4)
89+#define XCURSOR_FILE_TOC_LEN (3 * 4)
90+
91+typedef struct _XcursorFileToc {
92+ XcursorUInt type; /* chunk type */
93+ XcursorUInt subtype; /* subtype (size for images) */
94+ XcursorUInt position; /* absolute position in file */
95+} XcursorFileToc;
96+
97+typedef struct _XcursorFileHeader {
98+ XcursorUInt magic; /* magic number */
99+ XcursorUInt header; /* byte length of header */
100+ XcursorUInt version; /* file version number */
101+ XcursorUInt ntoc; /* number of toc entries */
102+ XcursorFileToc *tocs; /* table of contents */
103+} XcursorFileHeader;
104+
105+/*
106+ * The rest of the file is a list of chunks, each tagged by type
107+ * and version.
108+ *
109+ * Chunk:
110+ * ChunkHeader
111+ * <extra type-specific header fields>
112+ * <type-specific data>
113+ *
114+ * ChunkHeader:
115+ * CARD32 header bytes in chunk header + type header
116+ * CARD32 type chunk type
117+ * CARD32 subtype chunk subtype
118+ * CARD32 version chunk type version
119+ */
120+
121+#define XCURSOR_CHUNK_HEADER_LEN (4 * 4)
122+
123+typedef struct _XcursorChunkHeader {
124+ XcursorUInt header; /* bytes in chunk header */
125+ XcursorUInt type; /* chunk type */
126+ XcursorUInt subtype; /* chunk subtype (size for images) */
127+ XcursorUInt version; /* version of this type */
128+} XcursorChunkHeader;
129+
130+/*
131+ * Here's a list of the known chunk types
132+ */
133+
134+/*
135+ * Comments consist of a 4-byte length field followed by
136+ * UTF-8 encoded text
137+ *
138+ * Comment:
139+ * ChunkHeader header chunk header
140+ * CARD32 length bytes in text
141+ * LISTofCARD8 text UTF-8 encoded text
142+ */
143+
144+#define XCURSOR_COMMENT_TYPE 0xfffe0001
145+#define XCURSOR_COMMENT_VERSION 1
146+#define XCURSOR_COMMENT_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (1 *4))
147+#define XCURSOR_COMMENT_COPYRIGHT 1
148+#define XCURSOR_COMMENT_LICENSE 2
149+#define XCURSOR_COMMENT_OTHER 3
150+#define XCURSOR_COMMENT_MAX_LEN 0x100000
151+
152+typedef struct _XcursorComment {
153+ XcursorUInt version;
154+ XcursorUInt comment_type;
155+ char *comment;
156+} XcursorComment;
157+
158+/*
159+ * Each cursor image occupies a separate image chunk.
160+ * The length of the image header follows the chunk header
161+ * so that future versions can extend the header without
162+ * breaking older applications
163+ *
164+ * Image:
165+ * ChunkHeader header chunk header
166+ * CARD32 width actual width
167+ * CARD32 height actual height
168+ * CARD32 xhot hot spot x
169+ * CARD32 yhot hot spot y
170+ * CARD32 delay animation delay
171+ * LISTofCARD32 pixels ARGB pixels
172+ */
173+
174+#define XCURSOR_IMAGE_TYPE 0xfffd0002
175+#define XCURSOR_IMAGE_VERSION 1
176+#define XCURSOR_IMAGE_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (5*4))
177+#define XCURSOR_IMAGE_MAX_SIZE 0x7fff /* 32767x32767 max cursor size */
178+
179+typedef struct _XcursorFile XcursorFile;
180+
181+struct _XcursorFile {
182+ void *closure;
183+ int (*read) (XcursorFile *file, unsigned char *buf, int len);
184+ int (*write) (XcursorFile *file, unsigned char *buf, int len);
185+ int (*seek) (XcursorFile *file, long offset, int whence);
186+};
187+
188+typedef struct _XcursorComments {
189+ int ncomment; /* number of comments */
190+ XcursorComment **comments; /* array of XcursorComment pointers */
191+} XcursorComments;
192+
193+/*
194+ * From libXcursor/src/file.c
195+ */
196+
197+static XcursorImage *
198+XcursorImageCreate (int width, int height)
199+{
200+ XcursorImage *image;
201+
202+ image = malloc (sizeof (XcursorImage) +
203+ width * height * sizeof (XcursorPixel));
204+ if (!image)
205+ return NULL;
206+ image->version = XCURSOR_IMAGE_VERSION;
207+ image->pixels = (XcursorPixel *) (image + 1);
208+ image->size = width > height ? width : height;
209+ image->width = width;
210+ image->height = height;
211+ image->delay = 0;
212+ return image;
213+}
214+
215+static void
216+XcursorImageDestroy (XcursorImage *image)
217+{
218+ free (image);
219+}
220+
221+static XcursorImages *
222+XcursorImagesCreate (int size)
223+{
224+ XcursorImages *images;
225+
226+ images = malloc (sizeof (XcursorImages) +
227+ size * sizeof (XcursorImage *));
228+ if (!images)
229+ return NULL;
230+ images->nimage = 0;
231+ images->images = (XcursorImage **) (images + 1);
232+ images->name = NULL;
233+ return images;
234+}
235+
236+void
237+XcursorImagesDestroy (XcursorImages *images)
238+{
239+ int n;
240+
241+ if (!images)
242+ return;
243+
244+ for (n = 0; n < images->nimage; n++)
245+ XcursorImageDestroy (images->images[n]);
246+ if (images->name)
247+ free (images->name);
248+ free (images);
249+}
250+
251+static void
252+XcursorImagesSetName (XcursorImages *images, const char *name)
253+{
254+ char *new;
255+
256+ if (!images || !name)
257+ return;
258+
259+ new = malloc (strlen (name) + 1);
260+
261+ if (!new)
262+ return;
263+
264+ strcpy (new, name);
265+ if (images->name)
266+ free (images->name);
267+ images->name = new;
268+}
269+
270+static XcursorBool
271+_XcursorReadUInt (XcursorFile *file, XcursorUInt *u)
272+{
273+ unsigned char bytes[4];
274+
275+ if (!file || !u)
276+ return XcursorFalse;
277+
278+ if ((*file->read) (file, bytes, 4) != 4)
279+ return XcursorFalse;
280+ *u = ((bytes[0] << 0) |
281+ (bytes[1] << 8) |
282+ (bytes[2] << 16) |
283+ (bytes[3] << 24));
284+ return XcursorTrue;
285+}
286+
287+static void
288+_XcursorFileHeaderDestroy (XcursorFileHeader *fileHeader)
289+{
290+ free (fileHeader);
291+}
292+
293+static XcursorFileHeader *
294+_XcursorFileHeaderCreate (int ntoc)
295+{
296+ XcursorFileHeader *fileHeader;
297+
298+ if (ntoc > 0x10000)
299+ return NULL;
300+ fileHeader = malloc (sizeof (XcursorFileHeader) +
301+ ntoc * sizeof (XcursorFileToc));
302+ if (!fileHeader)
303+ return NULL;
304+ fileHeader->magic = XCURSOR_MAGIC;
305+ fileHeader->header = XCURSOR_FILE_HEADER_LEN;
306+ fileHeader->version = XCURSOR_FILE_VERSION;
307+ fileHeader->ntoc = ntoc;
308+ fileHeader->tocs = (XcursorFileToc *) (fileHeader + 1);
309+ return fileHeader;
310+}
311+
312+static XcursorFileHeader *
313+_XcursorReadFileHeader (XcursorFile *file)
314+{
315+ XcursorFileHeader head, *fileHeader;
316+ XcursorUInt skip;
317+ unsigned int n;
318+
319+ if (!file)
320+ return NULL;
321+
322+ if (!_XcursorReadUInt (file, &head.magic))
323+ return NULL;
324+ if (head.magic != XCURSOR_MAGIC)
325+ return NULL;
326+ if (!_XcursorReadUInt (file, &head.header))
327+ return NULL;
328+ if (!_XcursorReadUInt (file, &head.version))
329+ return NULL;
330+ if (!_XcursorReadUInt (file, &head.ntoc))
331+ return NULL;
332+ skip = head.header - XCURSOR_FILE_HEADER_LEN;
333+ if (skip)
334+ if ((*file->seek) (file, skip, SEEK_CUR) == EOF)
335+ return NULL;
336+ fileHeader = _XcursorFileHeaderCreate (head.ntoc);
337+ if (!fileHeader)
338+ return NULL;
339+ fileHeader->magic = head.magic;
340+ fileHeader->header = head.header;
341+ fileHeader->version = head.version;
342+ fileHeader->ntoc = head.ntoc;
343+ for (n = 0; n < fileHeader->ntoc; n++)
344+ {
345+ if (!_XcursorReadUInt (file, &fileHeader->tocs[n].type))
346+ break;
347+ if (!_XcursorReadUInt (file, &fileHeader->tocs[n].subtype))
348+ break;
349+ if (!_XcursorReadUInt (file, &fileHeader->tocs[n].position))
350+ break;
351+ }
352+ if (n != fileHeader->ntoc)
353+ {
354+ _XcursorFileHeaderDestroy (fileHeader);
355+ return NULL;
356+ }
357+ return fileHeader;
358+}
359+
360+static XcursorBool
361+_XcursorSeekToToc (XcursorFile *file,
362+ XcursorFileHeader *fileHeader,
363+ int toc)
364+{
365+ if (!file || !fileHeader || \
366+ (*file->seek) (file, fileHeader->tocs[toc].position, SEEK_SET) == EOF)
367+ return XcursorFalse;
368+ return XcursorTrue;
369+}
370+
371+static XcursorBool
372+_XcursorFileReadChunkHeader (XcursorFile *file,
373+ XcursorFileHeader *fileHeader,
374+ int toc,
375+ XcursorChunkHeader *chunkHeader)
376+{
377+ if (!file || !fileHeader || !chunkHeader)
378+ return XcursorFalse;
379+ if (!_XcursorSeekToToc (file, fileHeader, toc))
380+ return XcursorFalse;
381+ if (!_XcursorReadUInt (file, &chunkHeader->header))
382+ return XcursorFalse;
383+ if (!_XcursorReadUInt (file, &chunkHeader->type))
384+ return XcursorFalse;
385+ if (!_XcursorReadUInt (file, &chunkHeader->subtype))
386+ return XcursorFalse;
387+ if (!_XcursorReadUInt (file, &chunkHeader->version))
388+ return XcursorFalse;
389+ /* sanity check */
390+ if (chunkHeader->type != fileHeader->tocs[toc].type ||
391+ chunkHeader->subtype != fileHeader->tocs[toc].subtype)
392+ return XcursorFalse;
393+ return XcursorTrue;
394+}
395+
396+#define dist(a,b) ((a) > (b) ? (a) - (b) : (b) - (a))
397+
398+static XcursorDim
399+_XcursorFindBestSize (XcursorFileHeader *fileHeader,
400+ XcursorDim size,
401+ int *nsizesp)
402+{
403+ unsigned int n;
404+ int nsizes = 0;
405+ XcursorDim bestSize = 0;
406+ XcursorDim thisSize;
407+
408+ if (!fileHeader || !nsizesp)
409+ return 0;
410+
411+ for (n = 0; n < fileHeader->ntoc; n++)
412+ {
413+ if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
414+ continue;
415+ thisSize = fileHeader->tocs[n].subtype;
416+ if (!bestSize || dist (thisSize, size) < dist (bestSize, size))
417+ {
418+ bestSize = thisSize;
419+ nsizes = 1;
420+ }
421+ else if (thisSize == bestSize)
422+ nsizes++;
423+ }
424+ *nsizesp = nsizes;
425+ return bestSize;
426+}
427+
428+static int
429+_XcursorFindImageToc (XcursorFileHeader *fileHeader,
430+ XcursorDim size,
431+ int count)
432+{
433+ unsigned int toc;
434+ XcursorDim thisSize;
435+
436+ if (!fileHeader)
437+ return 0;
438+
439+ for (toc = 0; toc < fileHeader->ntoc; toc++)
440+ {
441+ if (fileHeader->tocs[toc].type != XCURSOR_IMAGE_TYPE)
442+ continue;
443+ thisSize = fileHeader->tocs[toc].subtype;
444+ if (thisSize != size)
445+ continue;
446+ if (!count)
447+ break;
448+ count--;
449+ }
450+ if (toc == fileHeader->ntoc)
451+ return -1;
452+ return toc;
453+}
454+
455+static XcursorImage *
456+_XcursorReadImage (XcursorFile *file,
457+ XcursorFileHeader *fileHeader,
458+ int toc)
459+{
460+ XcursorChunkHeader chunkHeader;
461+ XcursorImage head;
462+ XcursorImage *image;
463+ int n;
464+ XcursorPixel *p;
465+
466+ if (!file || !fileHeader)
467+ return NULL;
468+
469+ if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader))
470+ return NULL;
471+ if (!_XcursorReadUInt (file, &head.width))
472+ return NULL;
473+ if (!_XcursorReadUInt (file, &head.height))
474+ return NULL;
475+ if (!_XcursorReadUInt (file, &head.xhot))
476+ return NULL;
477+ if (!_XcursorReadUInt (file, &head.yhot))
478+ return NULL;
479+ if (!_XcursorReadUInt (file, &head.delay))
480+ return NULL;
481+ /* sanity check data */
482+ if (head.width >= 0x10000 || head.height > 0x10000)
483+ return NULL;
484+ if (head.width == 0 || head.height == 0)
485+ return NULL;
486+ if (head.xhot > head.width || head.yhot > head.height)
487+ return NULL;
488+
489+ /* Create the image and initialize it */
490+ image = XcursorImageCreate (head.width, head.height);
491+ if (image == NULL)
492+ return NULL;
493+ if (chunkHeader.version < image->version)
494+ image->version = chunkHeader.version;
495+ image->size = chunkHeader.subtype;
496+ image->xhot = head.xhot;
497+ image->yhot = head.yhot;
498+ image->delay = head.delay;
499+ n = image->width * image->height;
500+ p = image->pixels;
501+ while (n--)
502+ {
503+ if (!_XcursorReadUInt (file, p))
504+ {
505+ XcursorImageDestroy (image);
506+ return NULL;
507+ }
508+ p++;
509+ }
510+ return image;
511+}
512+
513+static XcursorImages *
514+XcursorXcFileLoadImages (XcursorFile *file, int size)
515+{
516+ XcursorFileHeader *fileHeader;
517+ XcursorDim bestSize;
518+ int nsize;
519+ XcursorImages *images;
520+ int n;
521+ int toc;
522+
523+ if (!file || size < 0)
524+ return NULL;
525+ fileHeader = _XcursorReadFileHeader (file);
526+ if (!fileHeader)
527+ return NULL;
528+ bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize);
529+ if (!bestSize)
530+ {
531+ _XcursorFileHeaderDestroy (fileHeader);
532+ return NULL;
533+ }
534+ images = XcursorImagesCreate (nsize);
535+ if (!images)
536+ {
537+ _XcursorFileHeaderDestroy (fileHeader);
538+ return NULL;
539+ }
540+ for (n = 0; n < nsize; n++)
541+ {
542+ toc = _XcursorFindImageToc (fileHeader, bestSize, n);
543+ if (toc < 0)
544+ break;
545+ images->images[images->nimage] = _XcursorReadImage (file, fileHeader,
546+ toc);
547+ if (!images->images[images->nimage])
548+ break;
549+ images->nimage++;
550+ }
551+ _XcursorFileHeaderDestroy (fileHeader);
552+ if (images->nimage != nsize)
553+ {
554+ XcursorImagesDestroy (images);
555+ images = NULL;
556+ }
557+ return images;
558+}
559+
560+static int
561+_XcursorStdioFileRead (XcursorFile *file, unsigned char *buf, int len)
562+{
563+ FILE *f = file->closure;
564+ return fread (buf, 1, len, f);
565+}
566+
567+static int
568+_XcursorStdioFileWrite (XcursorFile *file, unsigned char *buf, int len)
569+{
570+ FILE *f = file->closure;
571+ return fwrite (buf, 1, len, f);
572+}
573+
574+static int
575+_XcursorStdioFileSeek (XcursorFile *file, long offset, int whence)
576+{
577+ FILE *f = file->closure;
578+ return fseek (f, offset, whence);
579+}
580+
581+static void
582+_XcursorStdioFileInitialize (FILE *stdfile, XcursorFile *file)
583+{
584+ file->closure = stdfile;
585+ file->read = _XcursorStdioFileRead;
586+ file->write = _XcursorStdioFileWrite;
587+ file->seek = _XcursorStdioFileSeek;
588+}
589+
590+static XcursorImages *
591+XcursorFileLoadImages (FILE *file, int size)
592+{
593+ XcursorFile f;
594+
595+ if (!file)
596+ return NULL;
597+
598+ _XcursorStdioFileInitialize (file, &f);
599+ return XcursorXcFileLoadImages (&f, size);
600+}
601+
602+/*
603+ * From libXcursor/src/library.c
604+ */
605+
606+#ifndef ICONDIR
607+#define ICONDIR "/usr/X11R6/lib/X11/icons"
608+#endif
609+
610+#ifndef XCURSORPATH
611+#define XCURSORPATH "~/.icons:/usr/share/icons:/usr/share/pixmaps:~/.cursors:/usr/share/cursors/xorg-x11:"ICONDIR
612+#endif
613+
614+static const char *
615+XcursorLibraryPath (void)
616+{
617+ static const char *path;
618+
619+ if (!path)
620+ {
621+ path = getenv ("XCURSOR_PATH");
622+ if (!path)
623+ path = XCURSORPATH;
624+ }
625+ return path;
626+}
627+
628+static void
629+_XcursorAddPathElt (char *path, const char *elt, int len)
630+{
631+ int pathlen = strlen (path);
632+
633+ /* append / if the path doesn't currently have one */
634+ if (path[0] == '\0' || path[pathlen - 1] != '/')
635+ {
636+ strcat (path, "/");
637+ pathlen++;
638+ }
639+ if (len == -1)
640+ len = strlen (elt);
641+ /* strip leading slashes */
642+ while (len && elt[0] == '/')
643+ {
644+ elt++;
645+ len--;
646+ }
647+ strncpy (path + pathlen, elt, len);
648+ path[pathlen + len] = '\0';
649+}
650+
651+static char *
652+_XcursorBuildThemeDir (const char *dir, const char *theme)
653+{
654+ const char *colon;
655+ const char *tcolon;
656+ char *full;
657+ char *home;
658+ int dirlen;
659+ int homelen;
660+ int themelen;
661+ int len;
662+
663+ if (!dir || !theme)
664+ return NULL;
665+
666+ colon = strchr (dir, ':');
667+ if (!colon)
668+ colon = dir + strlen (dir);
669+
670+ dirlen = colon - dir;
671+
672+ tcolon = strchr (theme, ':');
673+ if (!tcolon)
674+ tcolon = theme + strlen (theme);
675+
676+ themelen = tcolon - theme;
677+
678+ home = NULL;
679+ homelen = 0;
680+ if (*dir == '~')
681+ {
682+ home = getenv ("HOME");
683+ if (!home)
684+ return NULL;
685+ homelen = strlen (home);
686+ dir++;
687+ dirlen--;
688+ }
689+
690+ /*
691+ * add space for any needed directory separators, one per component,
692+ * and one for the trailing null
693+ */
694+ len = 1 + homelen + 1 + dirlen + 1 + themelen + 1;
695+
696+ full = malloc (len);
697+ if (!full)
698+ return NULL;
699+ full[0] = '\0';
700+
701+ if (home)
702+ _XcursorAddPathElt (full, home, -1);
703+ _XcursorAddPathElt (full, dir, dirlen);
704+ _XcursorAddPathElt (full, theme, themelen);
705+ return full;
706+}
707+
708+static char *
709+_XcursorBuildFullname (const char *dir, const char *subdir, const char *file)
710+{
711+ char *full;
712+
713+ if (!dir || !subdir || !file)
714+ return NULL;
715+
716+ full = malloc (strlen (dir) + 1 + strlen (subdir) + 1 + strlen (file) + 1);
717+ if (!full)
718+ return NULL;
719+ full[0] = '\0';
720+ _XcursorAddPathElt (full, dir, -1);
721+ _XcursorAddPathElt (full, subdir, -1);
722+ _XcursorAddPathElt (full, file, -1);
723+ return full;
724+}
725+
726+static const char *
727+_XcursorNextPath (const char *path)
728+{
729+ char *colon = strchr (path, ':');
730+
731+ if (!colon)
732+ return NULL;
733+ return colon + 1;
734+}
735+
736+#define XcursorWhite(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
737+#define XcursorSep(c) ((c) == ';' || (c) == ',')
738+
739+static char *
740+_XcursorThemeInherits (const char *full)
741+{
742+ char line[8192];
743+ char *result = NULL;
744+ FILE *f;
745+
746+ if (!full)
747+ return NULL;
748+
749+ f = fopen (full, "r");
750+ if (f)
751+ {
752+ while (fgets (line, sizeof (line), f))
753+ {
754+ if (!strncmp (line, "Inherits", 8))
755+ {
756+ char *l = line + 8;
757+ char *r;
758+ while (*l == ' ') l++;
759+ if (*l != '=') continue;
760+ l++;
761+ while (*l == ' ') l++;
762+ result = malloc (strlen (l) + 1);
763+ if (result)
764+ {
765+ r = result;
766+ while (*l)
767+ {
768+ while (XcursorSep(*l) || XcursorWhite (*l)) l++;
769+ if (!*l)
770+ break;
771+ if (r != result)
772+ *r++ = ':';
773+ while (*l && !XcursorWhite(*l) &&
774+ !XcursorSep(*l))
775+ *r++ = *l++;
776+ }
777+ *r++ = '\0';
778+ }
779+ break;
780+ }
781+ }
782+ fclose (f);
783+ }
784+ return result;
785+}
786+
787+static FILE *
788+XcursorScanTheme (const char *theme, const char *name)
789+{
790+ FILE *f = NULL;
791+ char *full;
792+ char *dir;
793+ const char *path;
794+ char *inherits = NULL;
795+ const char *i;
796+
797+ if (!theme || !name)
798+ return NULL;
799+
800+ /*
801+ * Scan this theme
802+ */
803+ for (path = XcursorLibraryPath ();
804+ path && f == NULL;
805+ path = _XcursorNextPath (path))
806+ {
807+ dir = _XcursorBuildThemeDir (path, theme);
808+ if (dir)
809+ {
810+ full = _XcursorBuildFullname (dir, "cursors", name);
811+ if (full)
812+ {
813+ f = fopen (full, "r");
814+ free (full);
815+ }
816+ if (!f && !inherits)
817+ {
818+ full = _XcursorBuildFullname (dir, "", "index.theme");
819+ if (full)
820+ {
821+ inherits = _XcursorThemeInherits (full);
822+ free (full);
823+ }
824+ }
825+ free (dir);
826+ }
827+ }
828+ /*
829+ * Recurse to scan inherited themes
830+ */
831+ for (i = inherits; i && f == NULL; i = _XcursorNextPath (i))
832+ f = XcursorScanTheme (i, name);
833+ if (inherits != NULL)
834+ free (inherits);
835+ return f;
836+}
837+
838+XcursorImages *
839+XcursorLibraryLoadImages (const char *file, const char *theme, int size)
840+{
841+ FILE *f = NULL;
842+ XcursorImages *images = NULL;
843+
844+ if (!file)
845+ return NULL;
846+
847+ if (theme)
848+ f = XcursorScanTheme (theme, file);
849+ if (!f)
850+ f = XcursorScanTheme ("default", file);
851+ if (f)
852+ {
853+ images = XcursorFileLoadImages (f, size);
854+ if (images)
855+ XcursorImagesSetName (images, file);
856+ fclose (f);
857+ }
858+ return images;
859+}
860+
861+static void
862+load_all_cursors_from_dir(const char *path, int size,
863+ void (*load_callback)(XcursorImages *, void *),
864+ void *user_data)
865+{
866+ FILE *f;
867+ DIR *dir = opendir(path);
868+ struct dirent *ent;
869+ char *full;
870+ XcursorImages *images;
871+
872+ if (!dir)
873+ return;
874+
875+ for(ent = readdir(dir); ent; ent = readdir(dir)) {
876+#ifdef _DIRENT_HAVE_D_TYPE
877+ if (ent->d_type != DT_UNKNOWN &&
878+ (ent->d_type != DT_REG && ent->d_type != DT_LNK))
879+ continue;
880+#endif
881+
882+ full = _XcursorBuildFullname(path, "", ent->d_name);
883+ if (!full)
884+ continue;
885+
886+ f = fopen(full, "r");
887+ if (!f) {
888+ free(full);
889+ continue;
890+ }
891+
892+ images = XcursorFileLoadImages(f, size);
893+
894+ if (images) {
895+ XcursorImagesSetName(images, ent->d_name);
896+ load_callback(images, user_data);
897+ }
898+
899+ fclose (f);
900+ free(full);
901+ }
902+
903+ closedir(dir);
904+}
905+
906+/** Load all the cursor of a theme
907+ *
908+ * This function loads all the cursor images of a given theme and its
909+ * inherited themes. Each cursor is loaded into an XcursorImages object
910+ * which is passed to the caller's load callback. If a cursor appears
911+ * more than once across all the inherited themes, the load callback
912+ * will be called multiple times, with possibly different XcursorImages
913+ * object which have the same name. The user is expected to destroy the
914+ * XcursorImages objects passed to the callback with
915+ * XcursorImagesDestroy().
916+ *
917+ * \param theme The name of theme that should be loaded
918+ * \param size The desired size of the cursor images
919+ * \param load_callback A callback function that will be called
920+ * for each cursor loaded. The first parameter is the XcursorImages
921+ * object representing the loaded cursor and the second is a pointer
922+ * to data provided by the user.
923+ * \param user_data The data that should be passed to the load callback
924+ */
925+void
926+xcursor_load_theme(const char *theme, int size,
927+ void (*load_callback)(XcursorImages *, void *),
928+ void *user_data)
929+{
930+ char *full, *dir;
931+ char *inherits = NULL;
932+ const char *path, *i;
933+
934+ if (!theme)
935+ theme = "default";
936+
937+ for (path = XcursorLibraryPath();
938+ path;
939+ path = _XcursorNextPath(path)) {
940+ dir = _XcursorBuildThemeDir(path, theme);
941+ if (!dir)
942+ continue;
943+
944+ full = _XcursorBuildFullname(dir, "cursors", "");
945+
946+ if (full) {
947+ load_all_cursors_from_dir(full, size, load_callback,
948+ user_data);
949+ free(full);
950+ }
951+
952+ if (!inherits) {
953+ full = _XcursorBuildFullname(dir, "", "index.theme");
954+ if (full) {
955+ inherits = _XcursorThemeInherits(full);
956+ free(full);
957+ }
958+ }
959+
960+ free(dir);
961+ }
962+
963+ for (i = inherits; i; i = _XcursorNextPath(i))
964+ xcursor_load_theme(i, size, load_callback, user_data);
965+
966+ if (inherits)
967+ free(inherits);
968+}
plugins/Cursor/3rd_party/xcursor/xcursor.hnew file+65
@@ -0,0 +1,65 @@
1+/*
2+ * Copyright © 2002 Keith Packard
3+ *
4+ * Permission to use, copy, modify, distribute, and sell this software and its
5+ * documentation for any purpose is hereby granted without fee, provided that
6+ * the above copyright notice appear in all copies and that both that
7+ * copyright notice and this permission notice appear in supporting
8+ * documentation, and that the name of Keith Packard not be used in
9+ * advertising or publicity pertaining to distribution of the software without
10+ * specific, written prior permission. Keith Packard makes no
11+ * representations about the suitability of this software for any purpose. It
12+ * is provided "as is" without express or implied warranty.
13+ *
14+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20+ * PERFORMANCE OF THIS SOFTWARE.
21+ */
22+
23+#ifndef XCURSOR_H
24+#define XCURSOR_H
25+
26+#include <stdint.h>
27+
28+
29+typedef int XcursorBool;
30+typedef uint32_t XcursorUInt;
31+
32+typedef XcursorUInt XcursorDim;
33+typedef XcursorUInt XcursorPixel;
34+
35+typedef struct _XcursorImage {
36+ XcursorUInt version; /* version of the image data */
37+ XcursorDim size; /* nominal size for matching */
38+ XcursorDim width; /* actual width */
39+ XcursorDim height; /* actual height */
40+ XcursorDim xhot; /* hot spot x (must be inside image) */
41+ XcursorDim yhot; /* hot spot y (must be inside image) */
42+ XcursorUInt delay; /* animation delay to next frame (ms) */
43+ XcursorPixel *pixels; /* pointer to pixels */
44+} XcursorImage;
45+
46+/*
47+ * Other data structures exposed by the library API
48+ */
49+typedef struct _XcursorImages {
50+ int nimage; /* number of images */
51+ XcursorImage **images; /* array of XcursorImage pointers */
52+ char *name; /* name used to load images */
53+} XcursorImages;
54+
55+XcursorImages *
56+XcursorLibraryLoadImages (const char *file, const char *theme, int size);
57+
58+void
59+XcursorImagesDestroy (XcursorImages *images);
60+
61+void
62+xcursor_load_theme(const char *theme, int size,
63+ void (*load_callback)(XcursorImages *, void *),
64+ void *user_data);
65+#endif
plugins/Cursor/CMakeLists.txtnew file+28
@@ -0,0 +1,28 @@
1+add_subdirectory(3rd_party)
2+
3+include_directories(
4+ ${CMAKE_CURRENT_SOURCE_DIR}
5+ ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/xcursor
6+ ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
7+)
8+
9+set(QMLPLUGIN_SRC
10+ plugin.cpp
11+ MousePointer.cpp
12+ CursorImageProvider.cpp
13+ # We need to run moc on this header
14+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirMousePointerInterface.h
15+ )
16+
17+add_library(Cursor-qml SHARED
18+ ${QMLPLUGIN_SRC}
19+ )
20+
21+target_link_libraries(Cursor-qml
22+ xcursorloader-static
23+ ${QT5PLATFORM_SUPPORT_LDFLAGS}
24+)
25+
26+qt5_use_modules(Cursor-qml Qml Quick DBus Network Gui Sql Concurrent Svg)
27+
28+add_unity8_plugin(Cursor 1.0 Cursor TARGETS Cursor-qml)
plugins/Cursor/Cursor.qmlnew file+28
@@ -0,0 +1,28 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Cursor 1.0 // For MousePointer
19+
20+MousePointer {
21+ id: mousePointer
22+
23+ Image {
24+ x: -mousePointer.hotspotX
25+ y: -mousePointer.hotspotY
26+ source: "image://cursor/" + mousePointer.themeName + "/" + mousePointer.cursorName
27+ }
28+}
plugins/Cursor/CursorImageProvider.cppnew file+191
@@ -0,0 +1,191 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "CursorImageProvider.h"
18+
19+#include <QDebug>
20+#include <QFile>
21+#include <QPainter>
22+#include <QSvgRenderer>
23+
24+CursorImageProvider *CursorImageProvider::m_instance = nullptr;
25+
26+/////
27+// BuiltInCursorImage
28+
29+BuiltInCursorImage::BuiltInCursorImage()
30+{
31+ const char *svgString =
32+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
33+ "<svg"
34+ " xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
35+ " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""
36+ " xmlns:svg=\"http://www.w3.org/2000/svg\""
37+ " xmlns=\"http://www.w3.org/2000/svg\""
38+ " version=\"1.1\">"
39+ " <path"
40+ " style=\"fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:40;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\""
41+ " d=\"M 20.504,50.94931 460.42533,518.14486 266.47603,515.61948 366.48114,719.16522 274.05218,770.68296 172.53185,559.56112 20.504,716.13476 Z\" />"
42+ "</svg>";
43+
44+ qimage = QImage(20, 32, QImage::Format_ARGB32);
45+ QPainter imagePainter(&qimage);
46+
47+ QSvgRenderer *svgRenderer = new QSvgRenderer(QByteArray(svgString));
48+ svgRenderer->render(&imagePainter);
49+ delete svgRenderer;
50+}
51+
52+/////
53+// XCursorImage
54+
55+XCursorImage::XCursorImage(const QString &theme, const QString &file)
56+ : xcursorImages(nullptr)
57+{
58+ xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme), 32);
59+ if (!xcursorImages) {
60+ return;
61+ }
62+
63+ bool loaded = false;
64+ for (int i = 0; i < xcursorImages->nimage && !loaded; ++i) {
65+ XcursorImage *xcursorImage = xcursorImages->images[i];
66+ if (xcursorImage->size == 32) {
67+
68+ qimage = QImage((uchar*)xcursorImage->pixels,
69+ xcursorImage->width, xcursorImage->height, QImage::Format_ARGB32);
70+
71+ hotspot.setX(xcursorImage->xhot);
72+ hotspot.setY(xcursorImage->yhot);
73+
74+ loaded = true;
75+ }
76+ }
77+}
78+
79+XCursorImage::~XCursorImage()
80+{
81+ XcursorImagesDestroy(xcursorImages);
82+}
83+
84+/////
85+// CursorImageProvider
86+
87+CursorImageProvider::CursorImageProvider()
88+ : QQuickImageProvider(QQuickImageProvider::Image)
89+{
90+ if (m_instance) {
91+ qFatal("Cannot have multiple CursorImageProvider instances");
92+ }
93+ m_instance = this;
94+}
95+
96+CursorImageProvider::~CursorImageProvider()
97+{
98+ {
99+ QList< QMap<QString, CursorImage*> > cursorList = m_cursors.values();
100+
101+ for (int i = 0; i < cursorList.count(); ++i) {
102+ QList<CursorImage*> cursorImageList = cursorList[i].values();
103+ for (int j = 0; j < cursorImageList.count(); ++j) {
104+ delete cursorImageList[j];
105+ }
106+ }
107+ }
108+
109+ m_cursors.clear();
110+ m_instance = nullptr;
111+}
112+
113+QImage CursorImageProvider::requestImage(const QString &cursorThemeAndName, QSize *size, const QSize & /*requestedSize*/)
114+{
115+ CursorImage *cursorImage = fetchCursor(cursorThemeAndName);
116+ size->setWidth(cursorImage->qimage.width());
117+ size->setHeight(cursorImage->qimage.height());
118+
119+ return cursorImage->qimage;
120+}
121+
122+QPoint CursorImageProvider::hotspot(const QString &themeName, const QString &cursorName)
123+{
124+ CursorImage *cursorImage = fetchCursor(themeName, cursorName);
125+ if (cursorImage) {
126+ return cursorImage->hotspot;
127+ } else {
128+ return QPoint(0,0);
129+ }
130+}
131+
132+CursorImage *CursorImageProvider::fetchCursor(const QString &cursorThemeAndName)
133+{
134+ QString themeName;
135+ QString cursorName;
136+ {
137+ QStringList themeAndNameList = cursorThemeAndName.split("/");
138+ if (themeAndNameList.size() != 2) {
139+ return nullptr;
140+ }
141+ themeName = themeAndNameList[0];
142+ cursorName = themeAndNameList[1];
143+ }
144+
145+ return fetchCursor(themeName, cursorName);
146+}
147+
148+CursorImage *CursorImageProvider::fetchCursor(const QString &themeName, const QString &cursorName)
149+{
150+ CursorImage *cursorImage = fetchCursorHelper(themeName, cursorName);
151+
152+ // Try some fallbacks
153+ if (cursorImage->qimage.isNull()) {
154+ if (cursorName == "ibeam") {
155+ qDebug() << "CursorImageProvider: \"ibeam\" not found, falling back to \"xterm\"";
156+ cursorImage = fetchCursorHelper(themeName, "xterm");
157+ } else if (cursorName == "xterm") {
158+ qDebug() << "CursorImageProvider: \"xterm\" not found, falling back to \"ibeam\"";
159+ cursorImage = fetchCursorHelper(themeName, "ibeam");
160+ }
161+ }
162+
163+ // if it all fails, there must be at least a left_ptr
164+ if (cursorImage->qimage.isNull() && cursorName != "left_ptr") {
165+ qDebug() << "CursorImageProvider:" << cursorName
166+ << "not found (nor its fallbacks, if any). Going for \"left_ptr\" as a last resort.";
167+ cursorImage = fetchCursorHelper(themeName, "left_ptr");
168+ }
169+
170+ if (cursorImage->qimage.isNull()) {
171+ // finally, go for the built-in cursor
172+ qWarning() << "CursorImageProvider: couldn't find any cursors. Using the built-in one";
173+ if (!m_builtInCursorImage) {
174+ m_builtInCursorImage.reset(new BuiltInCursorImage);
175+ }
176+ cursorImage = m_builtInCursorImage.data();
177+ }
178+
179+ return cursorImage;
180+}
181+
182+CursorImage *CursorImageProvider::fetchCursorHelper(const QString &themeName, const QString &cursorName)
183+{
184+ QMap<QString, CursorImage*> &themeCursors = m_cursors[themeName];
185+
186+ if (!themeCursors.contains(cursorName)) {
187+ themeCursors[cursorName] = new XCursorImage(themeName, cursorName);
188+ }
189+
190+ return themeCursors[cursorName];
191+}
plugins/Cursor/CursorImageProvider.hnew file+76
@@ -0,0 +1,76 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef CURSORIMAGEPROVIDER_H
18+#define CURSORIMAGEPROVIDER_H
19+
20+#include <QQuickImageProvider>
21+#include <QScopedPointer>
22+
23+// xcursor static lib
24+extern "C"
25+{
26+#include <xcursor.h>
27+}
28+
29+class CursorImage {
30+public:
31+ virtual ~CursorImage() {}
32+
33+ QImage qimage;
34+ QPoint hotspot;
35+};
36+
37+class XCursorImage : public CursorImage {
38+public:
39+ XCursorImage(const QString &theme, const QString &file);
40+ virtual ~XCursorImage();
41+
42+ XcursorImages *xcursorImages;
43+};
44+
45+class BuiltInCursorImage : public CursorImage {
46+public:
47+ BuiltInCursorImage();
48+};
49+
50+class CursorImageProvider : public QQuickImageProvider
51+{
52+public:
53+ CursorImageProvider();
54+ virtual ~CursorImageProvider();
55+
56+ static CursorImageProvider *instance() { return m_instance; }
57+
58+
59+ QImage requestImage(const QString &cursorName, QSize *size, const QSize &requestedSize) override;
60+
61+ QPoint hotspot(const QString &themeName, const QString &cursorName);
62+
63+private:
64+ CursorImage *fetchCursor(const QString &cursorThemeAndName);
65+ CursorImage *fetchCursor(const QString &themeName, const QString &cursorName);
66+ CursorImage *fetchCursorHelper(const QString &themeName, const QString &cursorName);
67+
68+ // themeName -> (cursorName -> cursorImage)
69+ QMap<QString, QMap<QString, CursorImage*> > m_cursors;
70+
71+ QScopedPointer<CursorImage> m_builtInCursorImage;
72+
73+ static CursorImageProvider *m_instance;
74+};
75+
76+#endif // CURSORIMAGEPROVIDER_H
plugins/Cursor/MousePointer.cppnew file+125
@@ -0,0 +1,125 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "MousePointer.h"
18+#include "CursorImageProvider.h"
19+
20+// Unity API
21+#include <unity/shell/application/MirPlatformCursor.h>
22+
23+#include <QQuickWindow>
24+#include <QGuiApplication>
25+
26+#include <qpa/qwindowsysteminterface.h>
27+
28+MousePointer::MousePointer(QQuickItem *parent)
29+ : MirMousePointerInterface(parent)
30+ , m_cursorName("left_ptr")
31+ , m_themeName("default")
32+ , m_hotspotX(0)
33+ , m_hotspotY(0)
34+{
35+}
36+
37+void MousePointer::handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
38+ Qt::KeyboardModifiers modifiers)
39+{
40+ if (!parentItem()) {
41+ return;
42+ }
43+
44+ qreal newX = x() + movement.x();
45+ if (newX < 0) {
46+ newX = 0;
47+ } else if (newX > parentItem()->width()) {
48+ newX = parentItem()->width();
49+ }
50+ setX(newX);
51+
52+ qreal newY = y() + movement.y();
53+ if (newY < 0) {
54+ newY = 0;
55+ } else if (newY > parentItem()->height()) {
56+ newY = parentItem()->height();
57+ }
58+ setY(newY);
59+
60+ QPointF scenePosition = mapToItem(nullptr, QPointF(0, 0));
61+ QWindowSystemInterface::handleMouseEvent(window(), timestamp, scenePosition /*local*/, scenePosition /*global*/,
62+ buttons, modifiers);
63+}
64+
65+void MousePointer::itemChange(ItemChange change, const ItemChangeData &value)
66+{
67+ if (change == ItemSceneChange) {
68+ registerWindow(value.window);
69+ }
70+}
71+
72+void MousePointer::registerWindow(QWindow *window)
73+{
74+ if (m_registeredWindow && window != m_registeredWindow) {
75+ auto previousCursor = dynamic_cast<MirPlatformCursor*>(m_registeredWindow->screen()->handle()->cursor());
76+ if (previousCursor) {
77+ previousCursor->setMousePointer(nullptr);
78+ } else {
79+ qCritical("QPlatformCursor is not a MirPlatformCursor! Cursor module only works in a Mir server.");
80+ }
81+ }
82+
83+ m_registeredWindow = window;
84+
85+ if (m_registeredWindow) {
86+ auto cursor = dynamic_cast<MirPlatformCursor*>(window->screen()->handle()->cursor());
87+ if (cursor) {
88+ cursor->setMousePointer(this);
89+ } else {
90+ qCritical("QPlaformCursor is not a MirPlatformCursor! Cursor module only works in Mir.");
91+ }
92+ }
93+}
94+
95+void MousePointer::setCursorName(const QString &cursorName)
96+{
97+ if (cursorName != m_cursorName) {
98+ m_cursorName = cursorName;
99+ Q_EMIT cursorNameChanged(m_cursorName);
100+ updateHotspot();
101+ }
102+}
103+
104+void MousePointer::updateHotspot()
105+{
106+ QPoint newHotspot = CursorImageProvider::instance()->hotspot(m_themeName, m_cursorName);
107+
108+ if (m_hotspotX != newHotspot.x()) {
109+ m_hotspotX = newHotspot.x();
110+ Q_EMIT hotspotXChanged(m_hotspotX);
111+ }
112+
113+ if (m_hotspotY != newHotspot.y()) {
114+ m_hotspotY = newHotspot.y();
115+ Q_EMIT hotspotYChanged(m_hotspotY);
116+ }
117+}
118+
119+void MousePointer::setThemeName(const QString &themeName)
120+{
121+ if (m_themeName != themeName) {
122+ m_themeName = themeName;
123+ Q_EMIT themeNameChanged(m_themeName);
124+ }
125+}
plugins/Cursor/MousePointer.hnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef MOUSEPOINTER_H
18+#define MOUSEPOINTER_H
19+
20+// Qt
21+#include <QPointer>
22+#include <QWindow>
23+
24+// Unity API
25+#include <unity/shell/application/MirMousePointerInterface.h>
26+
27+class MousePointer : public MirMousePointerInterface {
28+ Q_OBJECT
29+public:
30+ MousePointer(QQuickItem *parent = nullptr);
31+
32+ void setCursorName(const QString &qtCursorName) override;
33+ QString cursorName() const override { return m_cursorName; }
34+
35+ void setThemeName(const QString &themeName) override;
36+ QString themeName() const override { return m_themeName; }
37+
38+ qreal hotspotX() const override { return m_hotspotX; }
39+ qreal hotspotY() const override { return m_hotspotY; }
40+
41+public Q_SLOTS:
42+ void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
43+ Qt::KeyboardModifiers modifiers) override;
44+
45+protected:
46+ void itemChange(ItemChange change, const ItemChangeData &value) override;
47+
48+private:
49+ void registerWindow(QWindow *window);
50+ void updateHotspot();
51+
52+ QPointer<QWindow> m_registeredWindow;
53+ QString m_cursorName;
54+ QString m_themeName;
55+ int m_hotspotX;
56+ int m_hotspotY;
57+};
58+
59+#endif // MOUSEPOINTER_H
plugins/Cursor/plugin.cppnew file+39
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+// Qt
18+#include <QtQml/qqml.h>
19+#include <QQmlContext>
20+
21+// self
22+#include "plugin.h"
23+
24+// local
25+#include "CursorImageProvider.h"
26+#include "MousePointer.h"
27+
28+void CursorPlugin::registerTypes(const char *uri)
29+{
30+ Q_ASSERT(uri == QLatin1String("Cursor"));
31+ qmlRegisterType<MousePointer>(uri, 1, 0, "MousePointer");
32+}
33+
34+void CursorPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
35+{
36+ QQmlExtensionPlugin::initializeEngine(engine, uri);
37+
38+ engine->addImageProvider(QLatin1String("cursor"), new CursorImageProvider());
39+}
plugins/Cursor/plugin.hnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef CURSOR_PLUGIN_H
18+#define CURSOR_PLUGIN_H
19+
20+#include <QtQml/QQmlEngine>
21+#include <QtQml/QQmlExtensionPlugin>
22+
23+class CursorPlugin : public QQmlExtensionPlugin
24+{
25+ Q_OBJECT
26+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
27+
28+public:
29+ void registerTypes(const char *uri) override;
30+ void initializeEngine(QQmlEngine *engine, const char *uri) override;
31+};
32+
33+#endif // CURSOR_PLUGIN_H
plugins/Cursor/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Cursor
2+plugin Cursor-qml
3+Cursor 1.0 Cursor.qml
plugins/Dash/CardAttributes.qml+3−3
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020
2121GridLayout {
2222 id: grid
@@ -27,7 +27,7 @@ GridLayout {
2727 columns: 2 + repeater.count % 2
2828 rowSpacing: units.gu(.5)
2929 property alias model: repeater.model
30− property color color: Theme.palette.normal.baseText
30+ property color color: theme.palette.normal.baseText
3131 property real fontScale: 1.0
3232
3333 Repeater {
plugins/Dash/CardCreator.js+26−52
@@ -28,11 +28,12 @@ var kBackgroundLoaderCode = 'Loader {\n\
2828 sourceComponent: UbuntuShape { \n\
2929 objectName: "background"; \n\
3030 radius: "medium"; \n\
31− color: getColor(0) || "white"; \n\
32− gradientColor: getColor(1) || color; \n\
31+ backgroundColor: getColor(0) || "white"; \n\
32+ secondaryBackgroundColor: getColor(1) || backgroundColor; \n\
33+ backgroundMode: UbuntuShape.VerticalGradient; \n\
3334 anchors.fill: parent; \n\
34− image: backgroundImage.source ? backgroundImage : null; \n\
35− property real luminance: Style.luminance(color); \n\
35+ source: backgroundImage.source ? backgroundImage : null; \n\
36+ property real luminance: Style.luminance(backgroundColor); \n\
3637 property Image backgroundImage: Image { \n\
3738 objectName: "backgroundImage"; \n\
3839 source: { \n\
@@ -52,7 +53,7 @@ var kBackgroundLoaderCode = 'Loader {\n\
5253// %1 is used as anchors of artShapeHolder
5354// %2 is used as image width
5455// %3 is used as image height
55−var kArtShapeHolderCode = 'Item { \n\
56+var kArtShapeHolderCode = 'Item { \n\
5657 id: artShapeHolder; \n\
5758 height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
5859 width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
@@ -66,10 +67,9 @@ var kArtShapeHolderCode = 'Item { \n\
6667 sourceComponent: Item { \n\
6768 id: artShape; \n\
6869 objectName: "artShape"; \n\
69− property bool doShapeItem: components["art"]["conciergeMode"] !== true; \n\
70+ readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true; \n\
7071 visible: image.status == Image.Ready; \n\
7172 readonly property alias image: artImage; \n\
72− property alias borderSource: artShapeShape.borderSource; \n\
7373 ShaderEffectSource { \n\
7474 id: artShapeSource; \n\
7575 sourceItem: artImage; \n\
@@ -78,16 +78,17 @@ var kArtShapeHolderCode = 'Item { \n\
7878 height: 1; \n\
7979 hideSource: doShapeItem; \n\
8080 } \n\
81− Shape { \n\
81+ UbuntuShape { \n\
8282 id: artShapeShape; \n\
83− image: artShapeSource; \n\
83+ source: artShapeSource; \n\
8484 anchors.fill: parent; \n\
8585 visible: doShapeItem; \n\
8686 radius: "medium"; \n\
87+ aspect: root.artShapeStyle === "inset" ? UbuntuShape.Inset : UbuntuShape.Flat; \n\
8788 } \n\
8889 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
8990 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
90− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
91+ Component.onCompleted: { updateWidthHeightBindings(); } \n\
9192 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
9293 function updateWidthHeightBindings() { \n\
9394 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
@@ -112,44 +113,18 @@ var kArtShapeHolderCode = 'Item { \n\
112113
113114var kOverlayLoaderCode = 'Loader { \n\
114115 id: overlayLoader; \n\
115− anchors { \n\
116− left: artShapeHolder.left; \n\
117− right: artShapeHolder.right; \n\
118− bottom: artShapeHolder.bottom; \n\
119− } \n\
116+ readonly property real overlayHeight: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
117+ anchors.fill: artShapeHolder; \n\
120118 active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \n\
121119 asynchronous: root.asynchronous; \n\
122120 visible: showHeader && status == Loader.Ready; \n\
123− sourceComponent: ShaderEffect { \n\
121+ sourceComponent: UbuntuShapeOverlay { \n\
124122 id: overlay; \n\
125− height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
126123 property real luminance: Style.luminance(overlayColor); \n\
127− property color overlayColor: cardData && cardData["overlayColor"] || "#99000000"; \n\
128− property var source: ShaderEffectSource { \n\
129− id: shaderSource; \n\
130− sourceItem: artShapeLoader.item; \n\
131− onVisibleChanged: if (visible) scheduleUpdate(); \n\
132− live: false; \n\
133− sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height); \n\
134− } \n\
135− vertexShader: " \n\
136− uniform highp mat4 qt_Matrix; \n\
137− attribute highp vec4 qt_Vertex; \n\
138− attribute highp vec2 qt_MultiTexCoord0; \n\
139− varying highp vec2 coord; \n\
140− void main() { \n\
141− coord = qt_MultiTexCoord0; \n\
142− gl_Position = qt_Matrix * qt_Vertex; \n\
143− }"; \n\
144− fragmentShader: " \n\
145− varying highp vec2 coord; \n\
146− uniform sampler2D source; \n\
147− uniform lowp float qt_Opacity; \n\
148− uniform highp vec4 overlayColor; \n\
149− void main() { \n\
150− lowp vec4 tex = texture2D(source, coord); \n\
151− gl_FragColor = vec4(overlayColor.r, overlayColor.g, overlayColor.b, 1) * qt_Opacity * overlayColor.a * tex.a; \n\
152− }"; \n\
124+ aspect: UbuntuShape.Flat; \n\
125+ radius: "medium"; \n\
126+ overlayColor: cardData && cardData["overlayColor"] || "#99000000"; \n\
127+ overlayRect: Qt.rect(0, 1 - overlayLoader.overlayHeight / height, 1, 1); \n\
153128 } \n\
154129 }\n';
155130
@@ -325,7 +300,7 @@ function cardString(template, components) {
325300 id: root; \n\
326301 property var components; \n\
327302 property var cardData; \n\
328− property var artShapeBorderSource: undefined; \n\
303+ property string artShapeStyle: "inset"; \n\
329304 property real fontScale: 1.0; \n\
330305 property var scopeStyle: null; \n\
331306 property int titleAlignment: Text.AlignLeft; \n\
@@ -368,7 +343,6 @@ function cardString(template, components) {
368343 }
369344
370345 if (hasArt) {
371− code += 'onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; } \n';
372346 code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);\n';
373347
374348 var widthCode, heightCode;
@@ -480,20 +454,20 @@ function cardString(template, components) {
480454 }
481455 }
482456
483− var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white")';
457+ var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white")';
484458
485459 var hasTitleContainer = hasTitle && (hasEmblem || (hasMascot && (hasSubtitle || hasAttributes)));
486460 var titleSubtitleCode = '';
487461 if (hasTitle) {
488462 var titleColor;
489463 if (headerAsOverlay) {
490− titleColor = 'root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white")';
464+ titleColor = 'root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white")';
491465 } else if (hasSummary) {
492466 titleColor = 'summary.color';
493467 } else if (hasBackground) {
494468 titleColor = summaryColorWithBackground;
495469 } else {
496− titleColor = 'root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText';
470+ titleColor = 'root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText';
497471 }
498472
499473 var titleAnchors;
@@ -555,7 +529,7 @@ function cardString(template, components) {
555529 titleAnchors += 'left: parent.left; \n\
556530 leftMargin: units.gu(1); \n\
557531 top: overlayLoader.top; \n\
558− topMargin: units.gu(1);\n';
532+ topMargin: units.gu(1) + overlayLoader.height - overlayLoader.overlayHeight; \n';
559533 } else {
560534 // Using anchors to the mascot/parent
561535 titleAnchors = titleRightAnchor;
@@ -649,7 +623,7 @@ function cardString(template, components) {
649623 if (hasBackground) {
650624 summaryColor = summaryColorWithBackground;
651625 } else {
652− summaryColor = 'root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText';
626+ summaryColor = 'root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText';
653627 }
654628
655629 var summaryTopMargin = (hasMascot || hasSubtitle || hasAttributes ? 'anchors.margins' : '0');
@@ -697,8 +671,8 @@ function cardString(template, components) {
697671}
698672
699673function createCardComponent(parent, template, components) {
700− var imports = 'import QtQuick 2.2; \n\
701− import Ubuntu.Components 1.1; \n\
674+ var imports = 'import QtQuick 2.4; \n\
675+ import Ubuntu.Components 1.3; \n\
702676 import Ubuntu.Settings.Components 0.1; \n\
703677 import Dash 0.1;\n\
704678 import Utils 0.1;\n';
plugins/Dash/CardCreatorCache.qml+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717pragma Singleton
18−import QtQuick 2.2
18+import QtQuick 2.4
1919import "CardCreator.js" as CardCreator
2020
2121QtObject {
plugins/Dash/CroppedImageMinimumSourceSize.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818
1919Image {
2020 id: root
plugins/Dash/ScopeStyle.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import Utils 0.1
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020
2121/*! \brief Helper for processing scope customization options.
2222
plugins/Dash/abstractdashview.h−4
@@ -109,11 +109,7 @@ private:
109109 virtual void doRelayout() = 0;
110110 virtual void updateItemCulling(qreal visibleFromY, qreal visibleToY) = 0;
111111 virtual void calculateImplicitHeight() = 0;
112−#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
113− virtual void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) = 0;
114−#else
115112 virtual void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) = 0;
116−#endif
117113
118114 QQmlDelegateModel *m_delegateModel;
119115
plugins/Dash/horizontaljournal.cpp−4
@@ -182,11 +182,7 @@ void HorizontalJournal::calculateImplicitHeight()
182182 }
183183}
184184
185−#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
186−void HorizontalJournal::processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes)
187−#else
188185void HorizontalJournal::processModelRemoves(const QVector<QQmlChangeSet::Change> &removes)
189−#endif
190186{
191187 Q_FOREACH(const QQmlChangeSet::Change &remove, removes) {
192188 for (int i = remove.count - 1; i >= 0; --i) {
plugins/Dash/horizontaljournal.h−4
@@ -52,11 +52,7 @@ private:
5252 void calculateImplicitHeight() override;
5353 void doRelayout() override;
5454 void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
55−#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
56− void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) override;
57−#else
5855 void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) override;
59−#endif
6056
6157 int m_firstVisibleIndex;
6258 QList<QQuickItem*> m_visibleItems;
plugins/Dash/organicgrid.cpp−4
@@ -235,11 +235,7 @@ void OrganicGrid::calculateImplicitHeight()
235235 }
236236}
237237
238−#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
239−void OrganicGrid::processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes)
240−#else
241238void OrganicGrid::processModelRemoves(const QVector<QQmlChangeSet::Change> &removes)
242−#endif
243239{
244240 Q_FOREACH(const QQmlChangeSet::Change &remove, removes) {
245241 for (int i = remove.count - 1; i >= 0; --i) {
plugins/Dash/organicgrid.h−4
@@ -79,11 +79,7 @@ private:
7979 void doRelayout() override;
8080 void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
8181 void calculateImplicitHeight() override;
82−#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
83− void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) override;
84−#else
8582 void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) override;
86−#endif
8783
8884 QSizeF m_smallDelegateSize;
8985 QSizeF m_bigDelegateSize;
plugins/Dash/verticaljournal.cpp−4
@@ -237,11 +237,7 @@ void VerticalJournal::updateItemCulling(qreal visibleFromY, qreal visibleToY)
237237 }
238238}
239239
240−#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
241−void VerticalJournal::processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes)
242−#else
243240void VerticalJournal::processModelRemoves(const QVector<QQmlChangeSet::Change> &removes)
244−#endif
245241{
246242 Q_FOREACH(const QQmlChangeSet::Change &remove, removes) {
247243 for (int i = remove.count - 1; i >= 0; --i) {
plugins/Dash/verticaljournal.h−4
@@ -90,11 +90,7 @@ private:
9090 void calculateImplicitHeight() override;
9191 void doRelayout() override;
9292 void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
93−#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
94− void processModelRemoves(const QVector<QQmlChangeSet::Remove> &removes) override;
95−#else
9693 void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) override;
97−#endif
9894
9995 QVector<QList<ViewItem>> m_columnVisibleItems;
10096 QHash<int, int> m_indexColumnMap;
plugins/IntegratedLightDM/UsersModel.cpp+7−6
@@ -43,16 +43,17 @@ MangleModel::MangleModel(QObject* parent)
4343
4444QVariant MangleModel::data(const QModelIndex &index, int role) const
4545{
46− QVariant data = QSortFilterProxyModel::data(index, role);
46+ QVariant variantData = QSortFilterProxyModel::data(index, role);
4747
4848 // If user's real name is empty, switch to unix name
49− if (role == QLightDM::UsersModel::RealNameRole && data.toString().isEmpty()) {
50− data = QSortFilterProxyModel::data(index, QLightDM::UsersModel::NameRole);
51− } else if (role == QLightDM::UsersModel::BackgroundPathRole && data.toString().startsWith('#')) {
52− data = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + data.toString() + "'/></svg>";
49+ if (role == QLightDM::UsersModel::RealNameRole && variantData.toString().isEmpty()) {
50+ variantData = QSortFilterProxyModel::data(index, QLightDM::UsersModel::NameRole);
51+ } else if (role == QLightDM::UsersModel::BackgroundPathRole && variantData.toString().startsWith('#')) {
52+ const QString stringData = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + variantData.toString() + "'/></svg>";
53+ variantData = stringData;
5354 }
5455
55− return data;
56+ return variantData;
5657}
5758
5859// **** Now we continue with actual UsersModel class ****
plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+2−1
@@ -34,7 +34,8 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
3434 entries.reserve(users.count());
3535 Q_FOREACH(const QString &user, users)
3636 {
37− QString name = settings.value(user + "/name", user[0].toUpper() + user.mid(1)).toString();
37+ QVariant defaultValue = QString(user[0].toUpper() + user.mid(1));
38+ QString name = settings.value(user + "/name", defaultValue).toString();
3839 entries.append({user, name, 0, 0, false, false, 0, 0});
3940 }
4041}
plugins/ScreenGrabber/screengrabber.cpp+2−2
@@ -60,7 +60,7 @@ ScreenGrabber::ScreenGrabber(QObject *parent)
6060 }
6161}
6262
63−void ScreenGrabber::captureAndSave()
63+void ScreenGrabber::captureAndSave(int angle)
6464{
6565 if (fileNamePrefix.isEmpty())
6666 {
@@ -82,7 +82,7 @@ void ScreenGrabber::captureAndSave()
8282 return;
8383 }
8484
85− const QImage screenshot = main_window->grabWindow();
85+ const QImage screenshot = main_window->grabWindow().transformed(QTransform().rotate(angle));
8686 const QString filename = makeFileName();
8787 qDebug() << "Saving screenshot to" << filename;
8888 auto saveOp = QtConcurrent::run(saveScreenshot, screenshot, filename, getFormat(), screenshotQuality);
plugins/ScreenGrabber/screengrabber.h+1−1
@@ -29,7 +29,7 @@ public:
2929 ~ScreenGrabber() = default;
3030
3131public Q_SLOTS:
32− void captureAndSave();
32+ void captureAndSave(int angle = 0);
3333
3434Q_SIGNALS:
3535 void screenshotSaved(const QString &filename);
plugins/Unity/CMakeLists.txt+1
@@ -4,3 +4,4 @@ add_subdirectory(Launcher)
44add_subdirectory(Session)
55add_subdirectory(DashCommunicator)
66add_subdirectory(InputInfo)
7+add_subdirectory(Platform)
plugins/Unity/Launcher/desktopfilehandler.cpp+3−2
@@ -111,8 +111,9 @@ QString DesktopFileHandler::displayName() const
111111 settings.beginGroup(QStringLiteral("Desktop Entry"));
112112
113113 // First try to find Name[xx_YY] and Name[xx] in .desktop file
114− QString locale = QLocale().name();
115− QString shortLocale = locale.split('_').first();
114+ const QString locale = QLocale().name();
115+ const QStringList splitLocale = locale.split(QLatin1Char('_'));
116+ const QString shortLocale = splitLocale.first();
116117
117118 if (locale != shortLocale && settings.contains(QStringLiteral("Name[%1]").arg(locale))) {
118119 return settings.value(QStringLiteral("Name[%1]").arg(locale)).toString();
plugins/Unity/Platform/CMakeLists.txtnew file+9
@@ -0,0 +1,9 @@
1+set(platformplugin_SRCS
2+ platform.cpp
3+ plugin.cpp)
4+
5+add_library(Platform-qml SHARED ${platformplugin_SRCS})
6+
7+qt5_use_modules(Platform-qml DBus Qml)
8+
9+add_unity8_plugin(Unity.Platform 1.0 Unity/Platform TARGETS Platform-qml)
plugins/Unity/Platform/platform.cppnew file+43
@@ -0,0 +1,43 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "platform.h"
18+
19+#include <QDBusConnection>
20+
21+Platform::Platform(QObject *parent)
22+ : QObject(parent)
23+ , m_iface("org.freedesktop.hostname1", "/org/freedesktop/hostname1", "org.freedesktop.hostname1",
24+ QDBusConnection::systemBus(), this)
25+{
26+ QMetaObject::invokeMethod(this, "init");
27+}
28+
29+void Platform::init()
30+{
31+ m_chassis = m_iface.property("Chassis").toString();
32+ m_isPC = (m_chassis == "desktop" || m_chassis == "laptop" || m_chassis == "server");
33+}
34+
35+QString Platform::chassis() const
36+{
37+ return m_chassis;
38+}
39+
40+bool Platform::isPC() const
41+{
42+ return m_isPC;
43+}
plugins/Unity/Platform/platform.hnew file+58
@@ -0,0 +1,58 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef PLATFORM_H
18+#define PLATFORM_H
19+
20+#include <QDBusInterface>
21+
22+/**
23+ * @brief The Platform class
24+ *
25+ * Wrapper around platform detection support (org.freedesktop.hostname1)
26+ */
27+class Platform: public QObject
28+{
29+ Q_OBJECT
30+ /**
31+ * The chassis property
32+ *
33+ * Supported values include: "laptop", "computer", "handset" or "tablet"
34+ * For full list see: http://www.freedesktop.org/wiki/Software/systemd/hostnamed/
35+ */
36+ Q_PROPERTY(QString chassis READ chassis CONSTANT)
37+ /**
38+ * Whether the machine is an ordinary PC (desktop, laptop or server)
39+ */
40+ Q_PROPERTY(bool isPC READ isPC CONSTANT)
41+
42+public:
43+ Platform(QObject *parent = nullptr);
44+ ~Platform() = default;
45+
46+ QString chassis() const;
47+ bool isPC() const;
48+
49+private Q_SLOTS:
50+ void init();
51+
52+private:
53+ QDBusInterface m_iface;
54+ QString m_chassis;
55+ bool m_isPC;
56+};
57+
58+#endif // PLATFORM_H
plugins/Unity/Platform/plugin.cppnew file+27
@@ -0,0 +1,27 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "platform.h"
19+
20+#include <QtQml>
21+
22+void GlobalShortcutPlugin::registerTypes(const char *uri)
23+{
24+ Q_ASSERT(uri == QLatin1String("Unity.Platform"));
25+
26+ qmlRegisterSingletonType<Platform>(uri, 1, 0, "Platform", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Platform; });
27+}
plugins/Utils/relativetimeformatter.h → plugins/Unity/Platform/plugin.hrenamed+10−12
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright (C) 2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,23 +12,21 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
1615 */
1716
18−#ifndef RELATIVETIMEFORMATTER_H
19−#define RELATIVETIMEFORMATTER_H
17+#ifndef PLATFORMPLUGIN_H
18+#define PLATFORMPLUGIN_H
2019
21−#include "timeformatter.h"
20+#include <QQmlExtensionPlugin>
2221
23−// TODO - move this to the sdk
24−// https://blueprints.launchpad.net/ubuntu-ui-toolkit/+spec/time-formatter
25−class RelativeTimeFormatter : public GDateTimeFormatter
22+class GlobalShortcutPlugin: public QQmlExtensionPlugin
2623{
2724 Q_OBJECT
28−public:
29− RelativeTimeFormatter(QObject *parent = 0);
25+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
3026
31− QString format() const override;
27+public:
28+ void registerTypes(const char *uri) override;
3229};
3330
34−#endif // RELATIVETIMEFORMATTER_H
31+
32+#endif // PLATFORMPLUGIN_H
plugins/Unity/Platform/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Unity.Platform
2+plugin Platform-qml
plugins/Unity/Session/dbusunitysessionservice.cpp+2−1
@@ -292,7 +292,8 @@ QString DBusUnitySessionService::RealName() const
292292 if (p) {
293293 const QString gecos = QString::fromLocal8Bit(p->pw_gecos);
294294 if (!gecos.isEmpty()) {
295− return gecos.split(QLatin1Char(',')).first();
295+ const QStringList splitGecos = gecos.split(QLatin1Char(','));
296+ return splitGecos.first();
296297 }
297298 }
298299
plugins/Utils/CMakeLists.txt−2
@@ -15,8 +15,6 @@ set(QMLPLUGIN_SRC
1515 inputwatcher.cpp
1616 qlimitproxymodelqml.cpp
1717 unitysortfilterproxymodelqml.cpp
18− relativetimeformatter.cpp
19− timeformatter.cpp
2018 Timer.cpp
2119 unitymenumodelpaths.cpp
2220 windowkeysfilter.cpp
plugins/Utils/plugin.cpp−5
@@ -29,8 +29,6 @@
2929#include "inputwatcher.h"
3030#include "qlimitproxymodelqml.h"
3131#include "unitysortfilterproxymodelqml.h"
32−#include "relativetimeformatter.h"
33−#include "timeformatter.h"
3432#include "unitymenumodelpaths.h"
3533#include "windowkeysfilter.h"
3634#include "windowscreenshotprovider.h"
@@ -60,11 +58,8 @@ void UtilsPlugin::registerTypes(const char *uri)
6058 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
6159 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
6260 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
63− qmlRegisterType<TimeFormatter>(uri, 0, 1, "TimeFormatter");
6461 qmlRegisterType<WindowKeysFilter>(uri, 0, 1, "WindowKeysFilter");
65− qmlRegisterType<GDateTimeFormatter>(uri, 0, 1, "GDateTimeFormatter");
6662 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
67− qmlRegisterType<RelativeTimeFormatter>(uri, 0, 1, "RelativeTimeFormatter");
6863 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
6964 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
7065 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
plugins/Utils/relativetimeformatter.cppdeleted−260
@@ -1,260 +0,0 @@
1−/*
2− * Copyright 2014 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− */
17−
18−// Local
19−#include "relativetimeformatter.h"
20−
21−// Qt
22−#include <QDateTime>
23−
24−// Other
25−#include <glib.h>
26−#include <glib/gi18n.h>
27−#include <locale.h>
28−#include <langinfo.h>
29−#include <string.h>
30−
31−RelativeTimeFormatter::RelativeTimeFormatter(QObject *parent)
32− : GDateTimeFormatter(parent)
33−{
34−}
35−
36− /* Check the system locale setting to see if the format is 24-hour
37− time or 12-hour time */
38−gboolean
39−is_locale_12h(void)
40−{
41− int i;
42− static const char *formats_24h[] = {"%H", "%R", "%T", "%OH", "%k", nullptr};
43− const char* t_fmt = nl_langinfo(T_FMT);
44−
45− for (i=0; formats_24h[i]!=nullptr; i++)
46− if (strstr(t_fmt, formats_24h[i]) != nullptr)
47− return FALSE;
48−
49− return TRUE;
50−}
51−
52−typedef enum
53−{
54− DATE_PROXIMITY_YESTERDAY,
55− DATE_PROXIMITY_TODAY,
56− DATE_PROXIMITY_TOMORROW,
57− DATE_PROXIMITY_LAST_WEEK,
58− DATE_PROXIMITY_NEXT_WEEK,
59− DATE_PROXIMITY_FAR
60−} date_proximity_t;
61−
62−static date_proximity_t
63−getDateProximity(GDateTime* now, GDateTime* time)
64−{
65− date_proximity_t prox = DATE_PROXIMITY_FAR;
66− gint now_year, now_month, now_day;
67− gint time_year, time_month, time_day;
68−
69− // does it happen today?
70− g_date_time_get_ymd(now, &now_year, &now_month, &now_day);
71− g_date_time_get_ymd(time, &time_year, &time_month, &time_day);
72− if ((now_year == time_year) && (now_month == time_month) && (now_day == time_day)) {
73− return DATE_PROXIMITY_TODAY;
74− }
75−
76− // did it happen yesterday?
77− GDateTime* yesterday = g_date_time_add_days(now, -1);
78− gint tom_year, tom_month, tom_day;
79− g_date_time_get_ymd(yesterday, &tom_year, &tom_month, &tom_day);
80− g_date_time_unref(yesterday);
81− if ((tom_year == time_year) && (tom_month == time_month) && (tom_day == time_day)) {
82− return DATE_PROXIMITY_YESTERDAY;
83− }
84−
85− // does it happen tomorrow?
86− GDateTime* tomorrow = g_date_time_add_days(now, 1);
87− g_date_time_get_ymd(tomorrow, &tom_year, &tom_month, &tom_day);
88− g_date_time_unref(tomorrow);
89− if ((tom_year == time_year) && (tom_month == time_month) && (tom_day == time_day)) {
90− return DATE_PROXIMITY_TOMORROW;
91− }
92−
93− // does it happen this week?
94− if (g_date_time_compare(time, now) < 0) {
95− GDateTime* last_week = g_date_time_add_days(now, -6);
96− GDateTime* last_week_bound = g_date_time_new_local(g_date_time_get_year(last_week),
97− g_date_time_get_month(last_week),
98− g_date_time_get_day_of_month(last_week),
99− 0, 0, 0);
100− if (g_date_time_compare(time, last_week_bound) >= 0)
101− prox = DATE_PROXIMITY_LAST_WEEK;
102−
103− g_date_time_unref(last_week);
104− g_date_time_unref(last_week_bound);
105− } else {
106− GDateTime* next_week = g_date_time_add_days(now, 6);
107− GDateTime* next_week_bound = g_date_time_new_local(g_date_time_get_year(next_week),
108− g_date_time_get_month(next_week),
109− g_date_time_get_day_of_month(next_week),
110− 23, 59, 59.9);
111− if (g_date_time_compare(time, next_week_bound) <= 0)
112− prox = DATE_PROXIMITY_NEXT_WEEK;
113−
114− g_date_time_unref(next_week);
115− g_date_time_unref(next_week_bound);
116− }
117−
118− return prox;
119−}
120−
121−const char*
122−dgettext_datetime(const char *text)
123−{
124− return dgettext("unity8", text);
125−}
126−
127−/**
128− * _ a time yesterday should be shown as (e.g. “Yesterday 3:55 PM”)
129− * _ a time today should be shown as just the time (e.g. “3:55 PM”)
130− * _ a time tomorrow should be shown as(e.g. “Tomorrow 3:55 PM”)
131− * _ a time any other day this week should be shown as the short version of the
132− * day and time (e.g. “Wed 3:55 PM”)
133− * weekday (e.g. “Friday”)
134− * _ a time after this week should be shown as the short version of the day,
135− * date, and time (e.g. “Wed 21 Apr 3:55 PM”)
136− * _ in addition, when presenting the times of upcoming events, the time should
137− * be followed by the timezone if it is different from the one the computer
138− * is currently set to. For example, “Wed 3:55 PM UTC−5”.
139− *
140− * TODO - keep inline with indicator-datetime
141− */
142−char* generate_full_format_string_at_time (GDateTime* now,
143− GDateTime* then)
144−{
145− GString* ret = g_string_new (nullptr);
146−
147− if (then != nullptr) {
148− const date_proximity_t prox = getDateProximity(now, then);
149−
150− if (is_locale_12h()) {
151− switch (prox) {
152− case DATE_PROXIMITY_YESTERDAY:
153− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
154− This format string is used for showing, on a 12-hour clock, times that happen yesterday.
155− (\u2003 is a unicode em space which is slightly wider than a normal space.)
156− en_US example: "Yesterday\u2003%l:%M %p" --> "Yesterday 1:00 PM" */
157− g_string_assign (ret, dgettext_datetime("Yesterday\u2003%l:%M %p"));
158− break;
159−
160− case DATE_PROXIMITY_TODAY:
161− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
162− This format string is used for showing, on a 12-hour clock, times that happened today.
163− en_US example: "%l:%M %p" --> "1:00 PM" */
164− g_string_assign (ret, dgettext_datetime("%l:%M %p"));
165− break;
166−
167− case DATE_PROXIMITY_TOMORROW:
168− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
169− This format string is used for showing, on a 12-hour clock, events/appointments that happen tomorrow.
170− (\u2003 is a unicode em space which is slightly wider than a normal space.)
171− en_US example: "Tomorrow\u2003%l:%M %p" --> "Tomorrow 1:00 PM" */
172− g_string_assign (ret, dgettext_datetime("Tomorrow\u2003%l:%M %p"));
173− break;
174−
175− case DATE_PROXIMITY_LAST_WEEK:
176− case DATE_PROXIMITY_NEXT_WEEK:
177− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
178− This format string is used for showing, on a 12-hour clock, times that happened in the last week.
179− (\u2003 is a unicode em space which is slightly wider than a normal space.)
180− en_US example: "%a\u2003%l:%M %p" --> "Fri 1:00 PM" */
181− g_string_assign (ret, dgettext_datetime("%a\u2003%l:%M %p"));
182− break;
183−
184− case DATE_PROXIMITY_FAR:
185− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
186− This format string is used for showing, on a 12-hour clock, times that happened before a week from now.
187− (\u2003 is a unicode em space which is slightly wider than a normal space.)
188− en_US example: "%a %b %d\u2003%l:%M %p" --> "Fri Oct 31 1:00 PM"
189− en_GB example: "%a %d %b\u2003%l:%M %p" --> "Fri 31 Oct 1:00 PM" */
190− g_string_assign (ret, dgettext_datetime("%a %d %b\u2003%l:%M %p"));
191− break;
192− }
193− } else {
194− switch (prox) {
195−
196− case DATE_PROXIMITY_YESTERDAY:
197− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
198− This format string is used for showing, on a 24-hour clock, times that happen yesterday.
199− (\u2003 is a unicode em space which is slightly wider than a normal space.)
200− en_US example: "Yesterday\u2003%l:%M %p" --> "Yesterday 13:00" */
201− g_string_assign (ret, dgettext_datetime("Yesterday\u2003%H:%M"));
202− break;
203−
204− case DATE_PROXIMITY_TODAY:
205− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
206− This format string is used for showing, on a 24-hour clock, times that happened today.
207− en_US example: "%H:%M" --> "13:00" */
208− g_string_assign (ret, dgettext_datetime("%H:%M"));
209− break;
210−
211− case DATE_PROXIMITY_TOMORROW:
212− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
213− This format string is used for showing, on a 24-hour clock, events/appointments that happen tomorrow.
214− (\u2003 is a unicode em space which is slightly wider than a normal space.)
215− en_US example: "Tomorrow\u2003%l:%M %p" --> "Tomorrow 13:00" */
216− g_string_assign (ret, dgettext_datetime("Tomorrow\u2003%H:%M"));
217− break;
218−
219− case DATE_PROXIMITY_LAST_WEEK:
220− case DATE_PROXIMITY_NEXT_WEEK:
221− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
222− This format string is used for showing, on a 24-hour clock, times that happened in the last week.
223− (\u2003 is a unicode em space which is slightly wider than a normal space.)
224− en_US example: "%a\u2003%H:%M" --> "Fri 13:00" */
225− g_string_assign (ret, dgettext_datetime("%a\u2003%H:%M"));
226− break;
227−
228− case DATE_PROXIMITY_FAR:
229− /* Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
230− This format string is used for showing, on a 24-hour clock, times that happened before a week from now.
231− (\u2003 is a unicode em space which is slightly wider than a normal space.)
232− en_US example: "%a %b %d\u2003%H:%M" --> "Fri Oct 31 13:00"
233− en_GB example: "%a %d %b\u2003%H:%M" --> "Fri 31 Oct 13:00" */
234− g_string_assign (ret, dgettext_datetime("%a %d %b\u2003%H:%M"));
235− break;
236− }
237− }
238− }
239−
240− return g_string_free (ret, FALSE);
241−}
242−
243−QString RelativeTimeFormatter::format() const
244−{
245− GDateTime* now = g_date_time_new_now_local();
246− if (!now) { return QString(); }
247−
248− GDateTime* then = g_date_time_new_from_unix_local(time());
249− if (!then) { return QString(); }
250−
251− char* time_format = generate_full_format_string_at_time(now, then);
252−
253− QString str(QString::fromUtf8(time_format));
254− g_free(time_format);
255−
256− g_date_time_unref(now);
257− g_date_time_unref(then);
258−
259− return str;
260−}
plugins/Utils/timeformatter.cppdeleted−206
@@ -1,206 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Lars Uebernickel <lars.uebernickel@canonical.com>
17− */
18−
19−#include "timeformatter.h"
20−
21−#include <gio/gio.h>
22−#include <QDateTime>
23−
24−struct TimeFormatterPrivate
25−{
26− TimeFormatter *formatter;
27−
28− QString format;
29− QString timeString;
30− qint64 time;
31−
32− GDBusConnection *system_bus;
33− guint subscription_id;
34− GCancellable *cancellable;
35−};
36−
37−static void
38−timedate1_properties_changed (GDBusConnection *connection,
39− const gchar *sender_name,
40− const gchar *object_path,
41− const gchar *interface_name,
42− const gchar *signal_name,
43− GVariant *parameters,
44− gpointer user_data)
45−{
46− Q_UNUSED(connection);
47− Q_UNUSED(sender_name);
48− Q_UNUSED(object_path);
49− Q_UNUSED(interface_name);
50− Q_UNUSED(signal_name);
51−
52− TimeFormatterPrivate *priv = (TimeFormatterPrivate *)user_data;
53− GVariant *changed;
54− GVariantIter *iter;
55− const gchar *name;
56−
57− if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sa{sv}as)")))
58− return;
59−
60− g_variant_get (parameters, "(s@a{sv}as)", nullptr, &changed, &iter);
61−
62− if (g_variant_lookup (changed, "Timezone", "s", nullptr)) {
63− priv->formatter->update();
64− }
65− else {
66− while (g_variant_iter_next (iter, "&s", &name)) {
67− if (g_str_equal (name, "Timezone")) {
68− priv->formatter->update();
69− break;
70− }
71− }
72− }
73−
74− g_variant_unref (changed);
75− g_variant_iter_free (iter);
76−}
77−
78−static void
79−got_bus(GObject *object, GAsyncResult *result, gpointer user_data)
80−{
81− Q_UNUSED(object);
82−
83− TimeFormatterPrivate *priv = (TimeFormatterPrivate *)user_data;
84− GError *error = nullptr;
85−
86− priv->system_bus = g_bus_get_finish (result, &error);
87− if (priv->system_bus == nullptr) {
88− if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
89− qWarning("TimeFormatter: cannot connect to the system bus: %s", error->message);
90− g_error_free (error);
91− return;
92− }
93−
94− /* Listen to the PropertiesChanged on the org.freedesktop.timedate1
95− * interface from any sender. In practice, this signal will only be sent
96− * from timedated (we can trust other processes on the system bus to behave
97− * nicely). That way, we don't have to watch timedated's well-known name
98− * and keep the process alive.
99− */
100− priv->subscription_id = g_dbus_connection_signal_subscribe (priv->system_bus,
101− nullptr, /* sender */
102− "org.freedesktop.DBus.Properties",
103− "PropertiesChanged",
104− nullptr,
105− "org.freedesktop.timedate1",
106− G_DBUS_SIGNAL_FLAGS_NONE,
107− timedate1_properties_changed,
108− priv, nullptr);
109−}
110−
111−TimeFormatter::TimeFormatter(QObject *parent): QObject(parent)
112−{
113− priv = new TimeFormatterPrivate;
114− priv->formatter = this;
115− priv->time = 0;
116− priv->format = QStringLiteral("yyyy-MM-dd hh:mm");
117− priv->system_bus = nullptr;
118− priv->subscription_id = 0;
119− priv->cancellable = g_cancellable_new ();
120−
121− g_bus_get (G_BUS_TYPE_SYSTEM, priv->cancellable, got_bus, priv);
122−}
123−
124−TimeFormatter::TimeFormatter(const QString &initialFormat, QObject *parent): TimeFormatter(parent)
125−{
126− priv->format = initialFormat;
127−}
128−
129−TimeFormatter::~TimeFormatter()
130−{
131− if (priv->system_bus) {
132− g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->subscription_id);
133− g_object_unref (priv->system_bus);
134− }
135−
136− g_cancellable_cancel (priv->cancellable);
137− g_object_unref (priv->cancellable);
138−}
139−
140−QString TimeFormatter::format() const
141−{
142− return priv->format;
143−}
144−
145−QString TimeFormatter::timeString() const
146−{
147− return priv->timeString;
148−}
149−
150−qint64 TimeFormatter::time() const
151−{
152− return priv->time;
153−}
154−
155−void TimeFormatter::setFormat(const QString &format)
156−{
157− if (priv->format != format) {
158− priv->format = format;
159− Q_EMIT formatChanged(priv->format);
160− update();
161− }
162−}
163−
164−void TimeFormatter::setTime(qint64 time)
165−{
166− if (priv->time != time) {
167− priv->time = time;
168− Q_EMIT timeChanged(priv->time);
169− update();
170− }
171−}
172−
173−void TimeFormatter::update()
174−{
175− priv->timeString = formatTime();
176− Q_EMIT timeStringChanged(priv->timeString);
177−}
178−
179−QString TimeFormatter::formatTime() const
180−{
181− return QDateTime::fromMSecsSinceEpoch(time() / 1000).toString(format());
182−}
183−
184−GDateTimeFormatter::GDateTimeFormatter(QObject* parent)
185−: TimeFormatter(QStringLiteral("%d-%m-%Y %I:%M%p"), parent)
186−{
187−}
188−
189−QString GDateTimeFormatter::formatTime() const
190−{
191− gchar* time_string;
192− GDateTime* datetime;
193− QByteArray formatBytes = format().toUtf8();
194−
195− datetime = g_date_time_new_from_unix_local(time());
196− if (!datetime) {
197− return QLatin1String("");
198− }
199−
200− time_string = g_date_time_format(datetime, formatBytes.constData());
201− QString formattedTime(QString::fromUtf8(time_string));
202−
203− g_free(time_string);
204− g_date_time_unref(datetime);
205− return formattedTime;
206−}
plugins/Utils/timeformatter.hdeleted−68
@@ -1,68 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Lars Uebernickel <lars.uebernickel@canonical.com>
17− */
18−
19−#ifndef TIME_FORMATTER_H
20−#define TIME_FORMATTER_H
21−
22−#include <QObject>
23−
24−// TODO - bug #1260728
25−class TimeFormatter : public QObject
26−{
27− Q_OBJECT
28− Q_PROPERTY(QString format READ format WRITE setFormat NOTIFY formatChanged)
29− Q_PROPERTY(QString timeString READ timeString NOTIFY timeStringChanged)
30− Q_PROPERTY(qint64 time READ time WRITE setTime NOTIFY timeChanged)
31−
32−public:
33− TimeFormatter(QObject *parent = 0);
34− virtual ~TimeFormatter();
35−
36− virtual QString format() const;
37− QString timeString() const;
38− qint64 time() const;
39−
40− void setFormat(const QString &format);
41− void setTime(qint64 time);
42−
43− void update();
44−
45−Q_SIGNALS:
46− void formatChanged(const QString &format);
47− void timeStringChanged(const QString &timeString);
48− void timeChanged(qint64 time);
49−
50−protected:
51− TimeFormatter(const QString &initialFormat, QObject *parent = 0);
52−
53− virtual QString formatTime() const;
54−
55−private:
56− struct TimeFormatterPrivate *priv;
57−};
58−
59−class GDateTimeFormatter : public TimeFormatter
60−{
61−public:
62− GDateTimeFormatter(QObject *parent = 0);
63−
64−protected:
65− QString formatTime() const override;
66−};
67−
68−#endif
plugins/Utils/timezoneFormatter.cpp+1−1
@@ -29,7 +29,7 @@ QString TimezoneFormatter::currentTimeInTimezone(const QVariant &tzId) const
2929 if (tz.isValid()) {
3030 const QDateTime now = QDateTime::currentDateTime().toTimeZone(tz);
3131 // return locale-aware string in the form "day, hh:mm", e.g. "Mon 14:30" or "Mon 1:30 pm"
32− return QStringLiteral("%1 %2").arg(now.toString("ddd")).arg(now.time().toString(Qt::DefaultLocaleShortDate));
32+ return QStringLiteral("%1 %2").arg(now.toString(QStringLiteral("ddd"))).arg(now.time().toString(Qt::DefaultLocaleShortDate));
3333 }
3434 return QString();
3535}
plugins/Utils/windowkeysfilter.cpp+15−1
@@ -21,7 +21,8 @@
2121#include <QQuickWindow>
2222
2323WindowKeysFilter::WindowKeysFilter(QQuickItem *parent)
24− : QQuickItem(parent)
24+ : QQuickItem(parent),
25+ m_currentEventTimestamp(0)
2526{
2627 connect(this, &QQuickItem::windowChanged,
2728 this, &WindowKeysFilter::setupFilterOnWindow);
@@ -36,7 +37,15 @@ bool WindowKeysFilter::eventFilter(QObject *watched, QEvent *event)
3637 if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
3738 // Let QML see this event and decide if it does not want it
3839 event->accept();
40+
41+ m_currentEventTimestamp = static_cast<QInputEvent*>(event)->timestamp();
42+ Q_EMIT currentEventTimestampChanged();
43+
3944 QCoreApplication::sendEvent(this, event);
45+
46+ m_currentEventTimestamp = 0;
47+ Q_EMIT currentEventTimestampChanged();
48+
4049 return event->isAccepted();
4150 } else {
4251 // Not interested
@@ -56,3 +65,8 @@ void WindowKeysFilter::setupFilterOnWindow(QQuickWindow *window)
5665 m_filteredWindow = window;
5766 }
5867}
68+
69+ulong WindowKeysFilter::currentEventTimestamp() const
70+{
71+ return m_currentEventTimestamp;
72+}
plugins/Utils/windowkeysfilter.h+7
@@ -36,16 +36,23 @@
3636class WindowKeysFilter : public QQuickItem
3737{
3838 Q_OBJECT
39+ Q_PROPERTY(ulong currentEventTimestamp READ currentEventTimestamp NOTIFY currentEventTimestampChanged)
3940public:
4041 WindowKeysFilter(QQuickItem *parent = 0);
4142
4243 bool eventFilter(QObject *watched, QEvent *event) override;
4344
45+ ulong currentEventTimestamp() const;
46+
47+Q_SIGNALS:
48+ void currentEventTimestampChanged();
49+
4450private Q_SLOTS:
4551 void setupFilterOnWindow(QQuickWindow *window);
4652
4753private:
4854 QPointer<QQuickWindow> m_filteredWindow;
55+ ulong m_currentEventTimestamp;
4956};
5057
5158#endif // UNITY_WINDOWKEYSFILTER_H
plugins/Utils/windowstatestorage.cpp+61−22
@@ -47,26 +47,38 @@ WindowStateStorage::~WindowStateStorage()
4747 m_db.close();
4848}
4949
50−void WindowStateStorage::saveGeometry(const QString &windowId, const QRect &rect)
50+void WindowStateStorage::saveState(const QString &windowId, WindowStateStorage::WindowState state)
5151{
52− QMutexLocker mutexLocker(&s_mutex);
52+ const QString queryString = QStringLiteral("INSERT OR REPLACE INTO state (windowId, state) values ('%1', '%2');")
53+ .arg(windowId)
54+ .arg((int)state);
55+
56+ saveValue(queryString);
57+}
58+
59+WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue) const
60+{
61+ const QString queryString = QStringLiteral("SELECT * FROM state WHERE windowId = '%1';")
62+ .arg(windowId);
5363
54− QString queryString = QStringLiteral("INSERT OR REPLACE INTO geometry (windowId, x, y, width, height) values ('%1', '%2', '%3', '%4', '%5');")
64+ QSqlQuery query = getValue(queryString);
65+
66+ if (!query.first()) {
67+ return defaultValue;
68+ }
69+ return (WindowState)query.value("state").toInt();
70+}
71+
72+void WindowStateStorage::saveGeometry(const QString &windowId, const QRect &rect)
73+{
74+ const QString queryString = QStringLiteral("INSERT OR REPLACE INTO geometry (windowId, x, y, width, height) values ('%1', '%2', '%3', '%4', '%5');")
5575 .arg(windowId)
5676 .arg(rect.x())
5777 .arg(rect.y())
5878 .arg(rect.width())
5979 .arg(rect.height());
6080
61− QFuture<void> future = QtConcurrent::run(executeAsyncQuery, queryString);
62− m_asyncQueries.append(future);
63−
64− QFutureWatcher<void> *futureWatcher = new QFutureWatcher<void>();
65− futureWatcher->setFuture(future);
66− connect(futureWatcher, &QFutureWatcher<void>::finished,
67− this,
68− [=](){ m_asyncQueries.removeAll(futureWatcher->future());
69− futureWatcher->deleteLater(); });
81+ saveValue(queryString);
7082}
7183
7284void WindowStateStorage::executeAsyncQuery(const QString &queryString)
@@ -82,20 +94,13 @@ void WindowStateStorage::executeAsyncQuery(const QString &queryString)
8294 }
8395}
8496
85−QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defaultValue)
97+QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defaultValue) const
8698{
87− QMutexLocker l(&s_mutex);
8899 QString queryString = QStringLiteral("SELECT * FROM geometry WHERE windowId = '%1';")
89100 .arg(windowId);
90− QSqlQuery query;
91101
92− bool ok = query.exec(queryString);
93− if (!ok) {
94− qWarning() << "Error retrieving window state for" << windowId
95− << "Driver error:" << query.lastError().driverText()
96− << "Database error:" << query.lastError().databaseText();
97− return defaultValue;
98− }
102+ QSqlQuery query = getValue(queryString);
103+
99104 if (!query.first()) {
100105 return defaultValue;
101106 }
@@ -114,4 +119,38 @@ void WindowStateStorage::initdb()
114119 QSqlQuery query;
115120 query.exec(QStringLiteral("CREATE TABLE geometry(windowId TEXT UNIQUE, x INTEGER, y INTEGER, width INTEGER, height INTEGER);"));
116121 }
122+
123+ if (!m_db.tables().contains("state")) {
124+ QSqlQuery query;
125+ query.exec("CREATE TABLE state(windowId TEXT UNIQUE, state INTEGER);");
126+ }
127+}
128+
129+void WindowStateStorage::saveValue(const QString &queryString)
130+{
131+ QMutexLocker mutexLocker(&s_mutex);
132+
133+ QFuture<void> future = QtConcurrent::run(executeAsyncQuery, queryString);
134+ m_asyncQueries.append(future);
135+
136+ QFutureWatcher<void> *futureWatcher = new QFutureWatcher<void>();
137+ futureWatcher->setFuture(future);
138+ connect(futureWatcher, &QFutureWatcher<void>::finished,
139+ this,
140+ [=](){ m_asyncQueries.removeAll(futureWatcher->future());
141+ futureWatcher->deleteLater(); });
142+}
143+
144+QSqlQuery WindowStateStorage::getValue(const QString &queryString) const
145+{
146+ QMutexLocker l(&s_mutex);
147+ QSqlQuery query;
148+
149+ bool ok = query.exec(queryString);
150+ if (!ok) {
151+ qWarning() << "Error retrieving database query:" << queryString
152+ << "Driver error:" << query.lastError().driverText()
153+ << "Database error:" << query.lastError().databaseText();
154+ }
155+ return query;
117156}
plugins/Utils/windowstatestorage.h+13−1
@@ -22,16 +22,28 @@
2222class WindowStateStorage: public QObject
2323{
2424 Q_OBJECT
25+ Q_ENUMS(WindowState)
2526public:
27+ enum WindowState {
28+ WindowStateNormal,
29+ WindowStateMaximized
30+ };
31+
2632 WindowStateStorage(QObject *parent = 0);
2733 virtual ~WindowStateStorage();
2834
35+ Q_INVOKABLE void saveState(const QString &windowId, WindowState state);
36+ Q_INVOKABLE WindowState getState(const QString &windowId, WindowState defaultValue) const;
37+
2938 Q_INVOKABLE void saveGeometry(const QString &windowId, const QRect &rect);
30− Q_INVOKABLE QRect getGeometry(const QString &windowId, const QRect &defaultValue);
39+ Q_INVOKABLE QRect getGeometry(const QString &windowId, const QRect &defaultValue) const;
3140
3241private:
3342 void initdb();
3443
44+ void saveValue(const QString &queryString);
45+ QSqlQuery getValue(const QString &queryString) const;
46+
3547 static void executeAsyncQuery(const QString &queryString);
3648 static QMutex s_mutex;
3749
po/ug.po+6−6
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2015-09-16 00:49+0200\n"
11−"PO-Revision-Date: 2015-10-02 03:54+0000\n"
11+"PO-Revision-Date: 2015-10-25 04:00+0000\n"
1212"Last-Translator: Eltikin <eltikinuyghur@hotmail.com>\n"
1313"Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-10-16 05:58+0000\n"
19−"X-Generator: Launchpad (build 17812)\n"
18+"X-Launchpad-Export-Date: 2015-10-28 05:39+0000\n"
19+"X-Generator: Launchpad (build 17833)\n"
2020
2121#: plugins/IntegratedLightDM/Greeter.cpp:112
2222msgid "Password: "
@@ -41,7 +41,7 @@ msgstr "تېزلەتمىنى ئېلىۋەت"
4141#. en_US example: "Yesterday\u2003%l:%M %p" --> "Yesterday 1:00 PM"
4242#: plugins/Utils/relativetimeformatter.cpp:157
4343msgid "Yesterday %l:%M %p"
44−msgstr ""
44+msgstr "تۈنۈگۈن %l:%M %p"
4545
4646#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
4747#. This format string is used for showing, on a 12-hour clock, times that happened today.
@@ -81,7 +81,7 @@ msgstr "%a %d %b %l:%M %p"
8181#. en_US example: "Yesterday\u2003%l:%M %p" --> "Yesterday 13:00"
8282#: plugins/Utils/relativetimeformatter.cpp:201
8383msgid "Yesterday %H:%M"
84−msgstr ""
84+msgstr "تۈنۈگۈن %H:%M"
8585
8686#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
8787#. This format string is used for showing, on a 24-hour clock, times that happened today.
@@ -502,7 +502,7 @@ msgstr ""
502502
503503#: qml/Tutorial/TutorialPage.qml:178
504504msgid "You almost got it!"
505−msgstr ""
505+msgstr "ھازىرلا پۈتۈرىدۇ!"
506506
507507#: qml/Tutorial/TutorialPage.qml:195
508508msgid "Try again."
po/unity8.pot+53−49
@@ -8,7 +8,7 @@ msgid ""
88msgstr ""
99"Project-Id-Version: unity8\n"
1010"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2015-09-16 00:49+0200\n"
11+"POT-Creation-Date: 2015-10-19 14:34+0100\n"
1212"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -69,8 +69,8 @@ msgstr ""
6969#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
7070#. This format string is used for showing, on a 12-hour clock, times that happened before a week from now.
7171#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
72−#. en_US example: "%a %d %b\u2003%l:%M %p" --> "Fri Oct 31 1:00 PM"
73−#. en_GB example: "%a %b %d\u2003%l:%M %p" --> "Fri 31 Oct 1:00 PM"
72+#. en_US example: "%a %b %d\u2003%l:%M %p" --> "Fri Oct 31 1:00 PM"
73+#. en_GB example: "%a %d %b\u2003%l:%M %p" --> "Fri 31 Oct 1:00 PM"
7474#: plugins/Utils/relativetimeformatter.cpp:190
7575msgid "%a %d %b %l:%M %p"
7676msgstr ""
@@ -109,8 +109,8 @@ msgstr ""
109109#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
110110#. This format string is used for showing, on a 24-hour clock, times that happened before a week from now.
111111#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
112−#. en_US example: "%a %d %b\u2003%H:%M" --> "Fri Oct 31 13:00"
113−#. en_GB example: "%a %b %d\u2003%H:%M" --> "Fri 31 Oct 13:00"
112+#. en_US example: "%a %b %d\u2003%H:%M" --> "Fri Oct 31 13:00"
113+#. en_GB example: "%a %d %b\u2003%H:%M" --> "Fri 31 Oct 13:00"
114114#: plugins/Utils/relativetimeformatter.cpp:234
115115msgid "%a %d %b %H:%M"
116116msgstr ""
@@ -286,6 +286,10 @@ msgstr ""
286286msgid "Add a review"
287287msgstr ""
288288
289+#: qml/Dash/Previews/PreviewSharing.qml:51
290+msgid "Preview Share Item"
291+msgstr ""
292+
289293#: qml/Dash/PullToRefreshScopeStyle.qml:55
290294msgid "Pull to refresh…"
291295msgstr ""
@@ -389,62 +393,62 @@ msgstr ""
389393msgid "Conference"
390394msgstr ""
391395
392−#: qml/Panel/Indicators/MenuItemFactory.qml:718
396+#: qml/Panel/Indicators/MenuItemFactory.qml:727
393397msgid "Nothing is playing"
394398msgstr ""
395399
396−#: qml/Panel/Indicators/MenuItemFactory.qml:847
400+#: qml/Panel/Indicators/MenuItemFactory.qml:856
397401#, qt-format
398402msgid "%1 hour"
399403msgid_plural "%1 hours"
400404msgstr[0] ""
401405msgstr[1] ""
402406
403−#: qml/Panel/Indicators/MenuItemFactory.qml:851
407+#: qml/Panel/Indicators/MenuItemFactory.qml:860
404408#, qt-format
405409msgid "%1 minute"
406410msgid_plural "%1 minutes"
407411msgstr[0] ""
408412msgstr[1] ""
409413
410−#: qml/Panel/Indicators/MenuItemFactory.qml:856
414+#: qml/Panel/Indicators/MenuItemFactory.qml:865
411415#, qt-format
412416msgid "%1 second"
413417msgid_plural "%1 seconds"
414418msgstr[0] ""
415419msgstr[1] ""
416420
417−#: qml/Panel/Indicators/MenuItemFactory.qml:859
421+#: qml/Panel/Indicators/MenuItemFactory.qml:868
418422msgid "0 seconds"
419423msgstr ""
420424
421425#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
422−#: qml/Panel/Indicators/MenuItemFactory.qml:861
426+#: qml/Panel/Indicators/MenuItemFactory.qml:870
423427#, qt-format
424428msgid "%1 remaining"
425429msgstr ""
426430
427−#: qml/Panel/Indicators/MenuItemFactory.qml:867
431+#: qml/Panel/Indicators/MenuItemFactory.qml:876
428432msgid "In queue…"
429433msgstr ""
430434
431−#: qml/Panel/Indicators/MenuItemFactory.qml:871
435+#: qml/Panel/Indicators/MenuItemFactory.qml:880
432436msgid "Downloading"
433437msgstr ""
434438
435−#: qml/Panel/Indicators/MenuItemFactory.qml:873
439+#: qml/Panel/Indicators/MenuItemFactory.qml:882
436440msgid "Paused, tap to resume"
437441msgstr ""
438442
439−#: qml/Panel/Indicators/MenuItemFactory.qml:875
443+#: qml/Panel/Indicators/MenuItemFactory.qml:884
440444msgid "Canceled"
441445msgstr ""
442446
443−#: qml/Panel/Indicators/MenuItemFactory.qml:877
447+#: qml/Panel/Indicators/MenuItemFactory.qml:886
444448msgid "Finished"
445449msgstr ""
446450
447−#: qml/Panel/Indicators/MenuItemFactory.qml:879
451+#: qml/Panel/Indicators/MenuItemFactory.qml:888
448452msgid "Failed, tap to retry"
449453msgstr ""
450454
@@ -523,38 +527,6 @@ msgctxt "Button: Go back one page in the Wizard"
523527msgid "Back"
524528msgstr ""
525529
526−#: qml/Wizard/Pages/here-terms.qml:27
527−msgid "Terms & Conditions"
528−msgstr ""
529−
530−#: qml/Wizard/Pages/passwd-confirm.qml:49
531−msgid "Confirm passphrase"
532−msgstr ""
533−
534−#: qml/Wizard/Pages/passwd-confirm.qml:50
535−msgid "Confirm passcode"
536−msgstr ""
537−
538−#: qml/Wizard/Pages/passwd-confirm.qml:53
539−#: qml/Wizard/Pages/passwd-confirm.qml:54
540−msgid "Please try again."
541−msgstr ""
542−
543−#: qml/Wizard/Pages/passwd-confirm.qml:82 qml/Wizard/Pages/passwd-set.qml:90
544−#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
545−#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
546−#: qml/Wizard/Pages/60-reporting.qml:50
547−msgid "Continue"
548−msgstr ""
549−
550−#: qml/Wizard/Pages/passwd-set.qml:61
551−msgid "Choose your passcode"
552−msgstr ""
553−
554−#: qml/Wizard/Pages/passwd-set.qml:68
555−msgid "Passphrase must be 4 characters long"
556−msgstr ""
557−
558530#: qml/Wizard/Pages/10-welcome.qml:27
559531msgid "Hi!"
560532msgstr ""
@@ -567,6 +539,13 @@ msgstr ""
567539msgid "Let’s get started."
568540msgstr ""
569541
542+#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
543+#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
544+#: qml/Wizard/Pages/60-reporting.qml:50 qml/Wizard/Pages/passwd-confirm.qml:82
545+#: qml/Wizard/Pages/passwd-set.qml:90
546+msgid "Continue"
547+msgstr ""
548+
570549#: qml/Wizard/Pages/20-sim.qml:25
571550msgid "Add a SIM card and restart your device"
572551msgstr ""
@@ -692,6 +671,31 @@ msgstr ""
692671msgid "Finish"
693672msgstr ""
694673
674+#: qml/Wizard/Pages/here-terms.qml:27
675+msgid "Terms & Conditions"
676+msgstr ""
677+
678+#: qml/Wizard/Pages/passwd-confirm.qml:49
679+msgid "Confirm passphrase"
680+msgstr ""
681+
682+#: qml/Wizard/Pages/passwd-confirm.qml:50
683+msgid "Confirm passcode"
684+msgstr ""
685+
686+#: qml/Wizard/Pages/passwd-confirm.qml:53
687+#: qml/Wizard/Pages/passwd-confirm.qml:54
688+msgid "Please try again."
689+msgstr ""
690+
691+#: qml/Wizard/Pages/passwd-set.qml:61
692+msgid "Choose your passcode"
693+msgstr ""
694+
695+#: qml/Wizard/Pages/passwd-set.qml:68
696+msgid "Passphrase must be 4 characters long"
697+msgstr ""
698+
695699#. Translators: This is the arrow for "Back" buttons
696700#: qml/Wizard/StackButton.qml:39
697701#, qt-format
po/wo.ponew file+800
@@ -0,0 +1,800 @@
1+# Wolof translation for unity8
2+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2015-09-16 00:49+0200\n"
11+"PO-Revision-Date: 2015-10-29 11:16+0000\n"
12+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13+"Language-Team: Wolof <wo@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n > 1;\n"
18+"X-Launchpad-Export-Date: 2015-10-30 05:32+0000\n"
19+"X-Generator: Launchpad (build 17838)\n"
20+
21+#: plugins/IntegratedLightDM/Greeter.cpp:112
22+msgid "Password: "
23+msgstr "Baatu-jàll "
24+
25+#: plugins/Unity/Launcher/launcheritem.cpp:47
26+#: plugins/Unity/Launcher/launcheritem.cpp:106
27+msgid "Pin shortcut"
28+msgstr "Kepp"
29+
30+#: plugins/Unity/Launcher/launcheritem.cpp:52
31+msgid "Quit"
32+msgstr "Génn"
33+
34+#: plugins/Unity/Launcher/launcheritem.cpp:106
35+msgid "Unpin shortcut"
36+msgstr "Dindi"
37+
38+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
39+#. This format string is used for showing, on a 12-hour clock, times that happen yesterday.
40+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
41+#. en_US example: "Yesterday\u2003%l:%M %p" --> "Yesterday 1:00 PM"
42+#: plugins/Utils/relativetimeformatter.cpp:157
43+msgid "Yesterday %l:%M %p"
44+msgstr "Démb %l:%M %p"
45+
46+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
47+#. This format string is used for showing, on a 12-hour clock, times that happened today.
48+#. en_US example: "%l:%M %p" --> "1:00 PM"
49+#: plugins/Utils/relativetimeformatter.cpp:164
50+msgid "%l:%M %p"
51+msgstr "%l:%M %p"
52+
53+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
54+#. This format string is used for showing, on a 12-hour clock, events/appointments that happen tomorrow.
55+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
56+#. en_US example: "Tomorrow\u2003%l:%M %p" --> "Tomorrow 1:00 PM"
57+#: plugins/Utils/relativetimeformatter.cpp:172
58+msgid "Tomorrow %l:%M %p"
59+msgstr "Suba ci %l:%M %p"
60+
61+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
62+#. This format string is used for showing, on a 12-hour clock, times that happened in the last week.
63+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
64+#. en_US example: "%a\u2003%l:%M %p" --> "Fri 1:00 PM"
65+#: plugins/Utils/relativetimeformatter.cpp:181
66+msgid "%a %l:%M %p"
67+msgstr "%a ci %l:%M %p"
68+
69+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
70+#. This format string is used for showing, on a 12-hour clock, times that happened before a week from now.
71+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
72+#. en_US example: "%a %d %b\u2003%l:%M %p" --> "Fri Oct 31 1:00 PM"
73+#. en_GB example: "%a %b %d\u2003%l:%M %p" --> "Fri 31 Oct 1:00 PM"
74+#: plugins/Utils/relativetimeformatter.cpp:190
75+msgid "%a %d %b %l:%M %p"
76+msgstr "%a %b %d ci %l:%M %p"
77+
78+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
79+#. This format string is used for showing, on a 24-hour clock, times that happen yesterday.
80+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
81+#. en_US example: "Yesterday\u2003%l:%M %p" --> "Yesterday 13:00"
82+#: plugins/Utils/relativetimeformatter.cpp:201
83+msgid "Yesterday %H:%M"
84+msgstr "Démb %H:%M"
85+
86+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
87+#. This format string is used for showing, on a 24-hour clock, times that happened today.
88+#. en_US example: "%H:%M" --> "13:00"
89+#: plugins/Utils/relativetimeformatter.cpp:208
90+msgid "%H:%M"
91+msgstr "%H:%M"
92+
93+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
94+#. This format string is used for showing, on a 24-hour clock, events/appointments that happen tomorrow.
95+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
96+#. en_US example: "Tomorrow\u2003%l:%M %p" --> "Tomorrow 13:00"
97+#: plugins/Utils/relativetimeformatter.cpp:216
98+msgid "Tomorrow %H:%M"
99+msgstr "Suba ci %H:%M"
100+
101+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
102+#. This format string is used for showing, on a 24-hour clock, times that happened in the last week.
103+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
104+#. en_US example: "%a\u2003%H:%M" --> "Fri 13:00"
105+#: plugins/Utils/relativetimeformatter.cpp:225
106+msgid "%a %H:%M"
107+msgstr "%a ci %H:%M"
108+
109+#. Translators, please edit/rearrange these strftime(3) tokens to suit your locale!
110+#. This format string is used for showing, on a 24-hour clock, times that happened before a week from now.
111+#. (\u2003 is a unicode em space which is slightly wider than a normal space.)
112+#. en_US example: "%a %d %b\u2003%H:%M" --> "Fri Oct 31 13:00"
113+#. en_GB example: "%a %b %d\u2003%H:%M" --> "Fri 31 Oct 13:00"
114+#: plugins/Utils/relativetimeformatter.cpp:234
115+msgid "%a %d %b %H:%M"
116+msgstr "%a %b %d ci %H:%M"
117+
118+#: qml/Components/DelayedLockscreen.qml:49
119+msgid "Device Locked"
120+msgstr "Téye nañ jumtukaay"
121+
122+#: qml/Components/DelayedLockscreen.qml:64
123+msgid "You have been locked out due to too many failed passphrase attempts."
124+msgstr "Téye nañ la ndax danga duggal ay yoon kàddu-jàll bu baaxul."
125+
126+#: qml/Components/DelayedLockscreen.qml:65
127+msgid "You have been locked out due to too many failed passcode attempts."
128+msgstr "Téye nañ la ndax danga duggal ay yoon kàddu-jàll bu baaxul."
129+
130+#: qml/Components/DelayedLockscreen.qml:74
131+#, qt-format
132+msgid "Please wait %1 minute and then try again…"
133+msgid_plural "Please wait %1 minutes and then try again…"
134+msgstr[0] "Dila ñaan nga xaar %1 simili te jéemaat..."
135+msgstr[1] "Dila ñaan nga xaar %1 simili te jéemaat..."
136+
137+#: qml/Components/Dialogs.qml:115
138+msgctxt "Title: Lock/Log out dialog"
139+msgid "Log out"
140+msgstr "Génn"
141+
142+#: qml/Components/Dialogs.qml:116
143+msgid "Are you sure you want to log out?"
144+msgstr "Wóor na ne danga bëgg a génn?"
145+
146+#: qml/Components/Dialogs.qml:118
147+msgctxt "Button: Lock the system"
148+msgid "Lock"
149+msgstr "Tëj"
150+
151+#: qml/Components/Dialogs.qml:125
152+msgctxt "Button: Log out from the system"
153+msgid "Log Out"
154+msgstr "Génn"
155+
156+#: qml/Components/Dialogs.qml:132 qml/Components/Dialogs.qml:165
157+#: qml/Components/Dialogs.qml:224
158+msgid "Cancel"
159+msgstr "Neenal"
160+
161+#: qml/Components/Dialogs.qml:144
162+msgctxt "Title: Reboot/Shut down dialog"
163+msgid "Shut down"
164+msgstr "Fay"
165+
166+#: qml/Components/Dialogs.qml:145
167+msgid "Are you sure you want to shut down?"
168+msgstr "Wóor na ne danga bëgg a fay?"
169+
170+#: qml/Components/Dialogs.qml:147
171+msgctxt "Button: Reboot the system"
172+msgid "Reboot"
173+msgstr "Fay-taalaat"
174+
175+#: qml/Components/Dialogs.qml:156
176+msgctxt "Button: Shut down the system"
177+msgid "Shut down"
178+msgstr "Fay"
179+
180+#: qml/Components/Dialogs.qml:178
181+msgctxt "Title: Reboot dialog"
182+msgid "Reboot"
183+msgstr "Fay-taalaat"
184+
185+#: qml/Components/Dialogs.qml:179
186+msgid "Are you sure you want to reboot?"
187+msgstr "Wóor na ne danga bëgg a fay-taalaat?"
188+
189+#: qml/Components/Dialogs.qml:181
190+msgid "No"
191+msgstr "Déet"
192+
193+#: qml/Components/Dialogs.qml:188
194+msgid "Yes"
195+msgstr "Waaw"
196+
197+#: qml/Components/Dialogs.qml:203
198+msgctxt "Title: Power off/Restart dialog"
199+msgid "Power"
200+msgstr "Fay"
201+
202+#: qml/Components/Dialogs.qml:204
203+msgid ""
204+"Are you sure you would like\n"
205+"to power off?"
206+msgstr "Wóor na ne danga bëgg a fay?"
207+
208+#: qml/Components/Dialogs.qml:206
209+msgctxt "Button: Power off the system"
210+msgid "Power off"
211+msgstr "Fay"
212+
213+#: qml/Components/Dialogs.qml:215
214+msgctxt "Button: Restart the system"
215+msgid "Restart"
216+msgstr "Fay-taalaat"
217+
218+#: qml/Components/Lockscreen.qml:245
219+msgid "Return to Call"
220+msgstr "Dellu ci woote bi"
221+
222+#: qml/Components/Lockscreen.qml:245
223+msgid "Emergency Call"
224+msgstr "Wooteb wallu"
225+
226+#: qml/Components/Lockscreen.qml:277
227+msgid "OK"
228+msgstr "OK"
229+
230+#: qml/Dash/GenericScopeView.qml:569 qml/Dash/GenericScopeView.qml:727
231+msgid "See less"
232+msgstr "Gis lu néew"
233+
234+#: qml/Dash/GenericScopeView.qml:569
235+msgid "See all"
236+msgstr "Gis lépp"
237+
238+#: qml/Dash/GenericScopeView.qml:631
239+msgctxt "Label: Hint for dash search line edit"
240+msgid "Search"
241+msgstr "Seet"
242+
243+#: qml/Dash/PageHeader.qml:269
244+msgctxt "Button: Open the Ubuntu Store"
245+msgid "Store"
246+msgstr "Ja"
247+
248+#: qml/Dash/PageHeader.qml:276
249+msgctxt "Button: Start a search in the current dash scope"
250+msgid "Search"
251+msgstr "Seet"
252+
253+#: qml/Dash/PageHeader.qml:286
254+msgctxt "Button: Show the current dash scope settings"
255+msgid "Settings"
256+msgstr "Jekkal"
257+
258+#: qml/Dash/PageHeader.qml:293
259+msgid "Remove from Favorites"
260+msgstr "Dindee ci Tànneef yi"
261+
262+#: qml/Dash/PageHeader.qml:293
263+msgid "Add to Favorites"
264+msgstr "Yokk ci Tànneef yi"
265+
266+#: qml/Dash/Previews/PreviewActionCombo.qml:35
267+msgid "More..."
268+msgstr "Leneen..."
269+
270+#: qml/Dash/Previews/PreviewActionCombo.qml:35
271+msgid "Less..."
272+msgstr "Wàññi..."
273+
274+#: qml/Dash/Previews/PreviewCommentInput.qml:68
275+#: qml/Dash/Previews/PreviewRatingInput.qml:174
276+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:148
277+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:205
278+msgid "Send"
279+msgstr "Yónnee"
280+
281+#: qml/Dash/Previews/PreviewRatingInput.qml:84
282+msgid "Rate this"
283+msgstr "Xayma ko"
284+
285+#: qml/Dash/Previews/PreviewRatingInput.qml:129
286+msgid "Add a review"
287+msgstr "Yokk sa xalaat"
288+
289+#: qml/Dash/PullToRefreshScopeStyle.qml:55
290+msgid "Pull to refresh…"
291+msgstr "Xëcc ngir yeesal..."
292+
293+#: qml/Dash/PullToRefreshScopeStyle.qml:60
294+msgid "Release to refresh…"
295+msgstr "Bàyyi ngir yeesal..."
296+
297+#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
298+msgid "Enable location data"
299+msgstr "Doxal njoxey barab"
300+
301+#: qml/Dash/ScopesList.qml:67
302+msgid "Manage"
303+msgstr "Yor"
304+
305+#: qml/Dash/ScopesList.qml:113
306+msgid "Home"
307+msgstr "Njëlbeen"
308+
309+#: qml/Dash/ScopesList.qml:114
310+msgid "Also installed"
311+msgstr "Yiñ samp tamit"
312+
313+#: qml/Greeter/CoverPage.qml:107
314+msgid "Unlock"
315+msgstr "Ubbi"
316+
317+#: qml/Greeter/LoginList.qml:236
318+msgid "Retry"
319+msgstr "Jéemaat"
320+
321+#: qml/Greeter/LoginList.qml:237
322+msgid "Tap to unlock"
323+msgstr "Bësal ngir ubbi"
324+
325+#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:53
326+msgid "Sorry, incorrect passphrase."
327+msgstr "Jéggalu, kàddu-jàll gi baaxul."
328+
329+#: qml/Greeter/NarrowView.qml:55 qml/Wizard/Pages/passwd-confirm.qml:54
330+msgid "Sorry, incorrect passcode."
331+msgstr "Jéggalu, baatu-jàll bi baaxul"
332+
333+#: qml/Greeter/NarrowView.qml:56
334+msgid "This will be your last attempt."
335+msgstr "Bii mooy sa jéem bu mujj."
336+
337+#: qml/Greeter/NarrowView.qml:58
338+msgid ""
339+"If passphrase is entered incorrectly, your phone will conduct a factory "
340+"reset and all personal data will be deleted."
341+msgstr ""
342+"Su kàddu-jàll gi dugg baaxul, sa wootekaay di nañ ko delloo nimu meloon ci "
343+"defaram te sa bépp njoxe di nañ ko far."
344+
345+#: qml/Greeter/NarrowView.qml:59
346+msgid ""
347+"If passcode is entered incorrectly, your phone will conduct a factory reset "
348+"and all personal data will be deleted."
349+msgstr ""
350+"Su baatu-jàll bi dugg baaxul, sa wootekaay di nañ ko delloo nimu meloon ci "
351+"defaram te sa bépp njoxe di nañ ko far."
352+
353+#: qml/Greeter/NarrowView.qml:116
354+#, qt-format
355+msgid "Enter %1"
356+msgstr "Bindal %1"
357+
358+#: qml/Greeter/NarrowView.qml:117 qml/Wizard/Pages/passwd-set.qml:60
359+msgid "Enter passphrase"
360+msgstr "Duggal kàddu-jàll"
361+
362+#: qml/Greeter/NarrowView.qml:118
363+msgid "Enter passcode"
364+msgstr "Duggal baatu-jàll"
365+
366+#: qml/Greeter/NarrowView.qml:119
367+#, qt-format
368+msgid "Sorry, incorrect %1"
369+msgstr "Jéggalu, %1 baaxul"
370+
371+#: qml/Greeter/NarrowView.qml:120
372+msgid "Sorry, incorrect passphrase"
373+msgstr "Jéggalu, kàddu-jàll gi baaxul"
374+
375+#: qml/Greeter/NarrowView.qml:121
376+msgctxt "passphrase"
377+msgid "Please re-enter"
378+msgstr "Di la ñaan nga duggalaat"
379+
380+#: qml/Greeter/NarrowView.qml:122
381+msgid "Sorry, incorrect passcode"
382+msgstr "Jéggalu, baatu-jàll bi baaxul"
383+
384+#: qml/Notifications/NotificationMenuItemFactory.qml:128
385+msgid "Show password"
386+msgstr "Wone baatu-jàll"
387+
388+#: qml/Panel/ActiveCallHint.qml:79
389+msgid "Tap to return to call..."
390+msgstr "Bësal ngir dello ci woote bi..."
391+
392+#: qml/Panel/ActiveCallHint.qml:92
393+msgid "Conference"
394+msgstr "Wax ci kaw"
395+
396+#: qml/Panel/Indicators/MenuItemFactory.qml:718
397+msgid "Nothing is playing"
398+msgstr "Dara dawul"
399+
400+#: qml/Panel/Indicators/MenuItemFactory.qml:847
401+#, qt-format
402+msgid "%1 hour"
403+msgid_plural "%1 hours"
404+msgstr[0] "%1 waxtu"
405+msgstr[1] "%1 waxtu"
406+
407+#: qml/Panel/Indicators/MenuItemFactory.qml:851
408+#, qt-format
409+msgid "%1 minute"
410+msgid_plural "%1 minutes"
411+msgstr[0] "%1 simili"
412+msgstr[1] "%1 simili"
413+
414+#: qml/Panel/Indicators/MenuItemFactory.qml:856
415+#, qt-format
416+msgid "%1 second"
417+msgid_plural "%1 seconds"
418+msgstr[0] "%1 saa"
419+msgstr[1] "%1 saa"
420+
421+#: qml/Panel/Indicators/MenuItemFactory.qml:859
422+msgid "0 seconds"
423+msgstr "0 saa"
424+
425+#. Translators: String like "1 hour, 2 minutes, 3 seconds remaining"
426+#: qml/Panel/Indicators/MenuItemFactory.qml:861
427+#, qt-format
428+msgid "%1 remaining"
429+msgstr "%1 moo des"
430+
431+#: qml/Panel/Indicators/MenuItemFactory.qml:867
432+msgid "In queue…"
433+msgstr "ci xaaruwaay bi..."
434+
435+#: qml/Panel/Indicators/MenuItemFactory.qml:871
436+msgid "Downloading"
437+msgstr "Yebbi"
438+
439+#: qml/Panel/Indicators/MenuItemFactory.qml:873
440+msgid "Paused, tap to resume"
441+msgstr "Dafa taxaw, bësal ngir tàmbaliwaat"
442+
443+#: qml/Panel/Indicators/MenuItemFactory.qml:875
444+msgid "Canceled"
445+msgstr "Neenalees"
446+
447+#: qml/Panel/Indicators/MenuItemFactory.qml:877
448+msgid "Finished"
449+msgstr "Jeexalees"
450+
451+#: qml/Panel/Indicators/MenuItemFactory.qml:879
452+msgid "Failed, tap to retry"
453+msgstr "Antoodi, bësal ngir jéemaat"
454+
455+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:149
456+msgctxt "Label: Hint in message indicator line edit"
457+msgid "Reply"
458+msgstr "Wuyu"
459+
460+#: qml/Panel/Indicators/MessageMenuItemFactory.qml:204
461+msgid "Call back"
462+msgstr "wootewaat"
463+
464+#: qml/Panel/Indicators/ModemInfoItem.qml:105
465+msgid "Unlock SIM"
466+msgstr "Tijji SIM"
467+
468+#: qml/Panel/Indicators/RoamingIndication.qml:27
469+msgid "Roaming"
470+msgstr "Roaming"
471+
472+#: qml/Tutorial/TutorialBottomFinish.qml:24
473+msgid "This action does different things for different apps"
474+msgstr "Jii jëf dafay defal mbir yu wuute jëfekaay yu wuute"
475+
476+#: qml/Tutorial/TutorialBottomFinish.qml:25
477+msgid "Tap here to finish."
478+msgstr "Bësal fii ngir Feexal."
479+
480+#: qml/Tutorial/TutorialBottom.qml:28
481+msgid "Open special menus"
482+msgstr "Open njëli jagleel"
483+
484+#: qml/Tutorial/TutorialBottom.qml:29
485+msgid "Swipe up from the bottom edge."
486+msgstr "Diri tambalee ci cat bu suuf bi."
487+
488+#: qml/Tutorial/TutorialContent.qml:80 qml/Tutorial/TutorialLeftFinish.qml:25
489+#: qml/Tutorial/TutorialRight.qml:144
490+msgid "Tap here to continue."
491+msgstr "Bësal fii ngir wéy."
492+
493+#: qml/Tutorial/TutorialLeftFinish.qml:24
494+msgid "These are the shortcuts to favorite apps"
495+msgstr "Yii ñall ñooy yóbbe ci jëfekaay yi nga taamu"
496+
497+#: qml/Tutorial/TutorialLeft.qml:26
498+msgid "Open the launcher"
499+msgstr "Ubbi Ubbikaay bi"
500+
501+#: qml/Tutorial/TutorialLeft.qml:27
502+msgid "Short swipe from the left edge."
503+msgstr "Diri bu gàtt tambalee ci cat bu cammoñ bi"
504+
505+#: qml/Tutorial/TutorialPage.qml:178
506+msgid "You almost got it!"
507+msgstr "Léegi mu jeex"
508+
509+#: qml/Tutorial/TutorialPage.qml:195
510+msgid "Try again."
511+msgstr "Jéemaatal"
512+
513+#: qml/Tutorial/TutorialRight.qml:31
514+msgid "To view open apps"
515+msgstr "Ngir gis jëfekaay yi ubeeku"
516+
517+#: qml/Tutorial/TutorialRight.qml:32
518+msgid "Long swipe from the right edge."
519+msgstr "Diri bu gudd tambalee ci cat bu ndijoor bi."
520+
521+#: qml/Tutorial/TutorialRight.qml:122
522+msgid "View all your running tasks."
523+msgstr "Gis lépp luy dox ci biir."
524+
525+#: qml/Wizard/Page.qml:89
526+msgctxt "Button: Go back one page in the Wizard"
527+msgid "Back"
528+msgstr "Dellu"
529+
530+#: qml/Wizard/Pages/here-terms.qml:27
531+msgid "Terms & Conditions"
532+msgstr "Anami jëfandiku gi"
533+
534+#: qml/Wizard/Pages/passwd-confirm.qml:49
535+msgid "Confirm passphrase"
536+msgstr "Dëggal kàddu-jàll"
537+
538+#: qml/Wizard/Pages/passwd-confirm.qml:50
539+msgid "Confirm passcode"
540+msgstr "Dëggal baatu-jàll"
541+
542+#: qml/Wizard/Pages/passwd-confirm.qml:53
543+#: qml/Wizard/Pages/passwd-confirm.qml:54
544+msgid "Please try again."
545+msgstr "Dila ñaan nga jéemaat."
546+
547+#: qml/Wizard/Pages/passwd-confirm.qml:82 qml/Wizard/Pages/passwd-set.qml:90
548+#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
549+#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
550+#: qml/Wizard/Pages/60-reporting.qml:50
551+msgid "Continue"
552+msgstr "Wéy"
553+
554+#: qml/Wizard/Pages/passwd-set.qml:61
555+msgid "Choose your passcode"
556+msgstr "Tànnal sa baatu-jàll"
557+
558+#: qml/Wizard/Pages/passwd-set.qml:68
559+msgid "Passphrase must be 4 characters long"
560+msgstr "Kàddu-jàll gi faww mu mat 4 màndarga"
561+
562+#: qml/Wizard/Pages/10-welcome.qml:27
563+msgid "Hi!"
564+msgstr "Dila nuyu!"
565+
566+#: qml/Wizard/Pages/10-welcome.qml:44
567+msgid "Welcome to your Ubuntu phone."
568+msgstr "Dala-jàmm ci sa wootekaay bu Ubuntu."
569+
570+#: qml/Wizard/Pages/10-welcome.qml:52
571+msgid "Let’s get started."
572+msgstr "Nu tambali."
573+
574+#: qml/Wizard/Pages/20-sim.qml:25
575+msgid "Add a SIM card and restart your device"
576+msgstr "Duggalal ab SIM te fay-taalaat sa wootekaay"
577+
578+#: qml/Wizard/Pages/20-sim.qml:59
579+msgid "Without it, you won’t be able to make calls or use text messaging."
580+msgstr "Lu ko moy doo man a woote walla yónney bataaxal."
581+
582+#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
583+msgid "Skip"
584+msgstr "Tëb"
585+
586+#: qml/Wizard/Pages/30-passwd-type.qml:39
587+msgid "Lock security"
588+msgstr "Kaaraangeg tëj"
589+
590+#: qml/Wizard/Pages/30-passwd-type.qml:74
591+msgid "Please select how you’d like to unlock your phone."
592+msgstr "Tànnal nan nga bëgg a tëjee sa wootekaay"
593+
594+#: qml/Wizard/Pages/30-passwd-type.qml:97
595+msgctxt "Label: Type of security method"
596+msgid "Swipe"
597+msgstr "Diri"
598+
599+#: qml/Wizard/Pages/30-passwd-type.qml:98
600+msgctxt "Label: Description of security method"
601+msgid "No security"
602+msgstr "Amul kaaraange"
603+
604+#: qml/Wizard/Pages/30-passwd-type.qml:100
605+msgctxt "Label: Type of security method"
606+msgid "Passcode"
607+msgstr "Baatu-jàll"
608+
609+#: qml/Wizard/Pages/30-passwd-type.qml:101
610+msgctxt "Label: Description of security method"
611+msgid "4 digits only"
612+msgstr "4 baaraam rek"
613+
614+#: qml/Wizard/Pages/30-passwd-type.qml:103
615+msgctxt "Label: Type of security method"
616+msgid "Passphrase"
617+msgstr "kàddu-jàll"
618+
619+#: qml/Wizard/Pages/30-passwd-type.qml:104
620+msgctxt "Label: Description of security method"
621+msgid "Numbers and letters"
622+msgstr "Nimero aki araf"
623+
624+#: qml/Wizard/Pages/40-wifi.qml:29
625+msgid "Connect to Wi‑Fi"
626+msgstr "Lonku ci Wi-fi"
627+
628+#: qml/Wizard/Pages/40-wifi.qml:168
629+msgid "Available networks…"
630+msgstr "Mbaal yi jàppandi..."
631+
632+#: qml/Wizard/Pages/40-wifi.qml:169
633+msgid "No available networks."
634+msgstr "Benn mbaal jàppandiwul"
635+
636+#: qml/Wizard/Pages/50-location.qml:27
637+msgid "Location"
638+msgstr "Nekkuwaay"
639+
640+#: qml/Wizard/Pages/50-location.qml:62
641+msgid "Let the phone detect your location:"
642+msgstr "Bàyyi wootekaay bi gisal boppam sa nekkuwaay"
643+
644+#: qml/Wizard/Pages/50-location.qml:69
645+msgid "Using GPS only (less accurate)"
646+msgstr "Ci jëfandikoo GPS kepp (gën a ñawadi)"
647+
648+#: qml/Wizard/Pages/50-location.qml:86
649+msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
650+msgstr ""
651+"Jëfandikoo GPS, wi-fi buñ xamul ak xibaaru mbaalu wootekaay (digalees)"
652+
653+#. Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
654+#: qml/Wizard/Pages/50-location.qml:103
655+msgid ""
656+"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
657+"conditions</a>."
658+msgstr ""
659+"Soo falee bii tànneef mooy ne nangu nga <a href='#'>anami jëfandiku</a gu "
660+"Nokia HERE"
661+
662+#: qml/Wizard/Pages/50-location.qml:112
663+msgid "Not at all"
664+msgstr "Déet"
665+
666+#: qml/Wizard/Pages/50-location.qml:124
667+msgid "You can change your mind later in <b>System Settings</b>."
668+msgstr "Man ngaa seetaat sa tànneef ginnaaw bi ci <b>Jekkali Noste</b>."
669+
670+#: qml/Wizard/Pages/60-reporting.qml:24
671+msgid "Improving your experience"
672+msgstr "Gënal jëfandiku gi"
673+
674+#: qml/Wizard/Pages/60-reporting.qml:36
675+msgid ""
676+"Your phone is set up to automatically report errors to Canonical and its "
677+"partners, the makers of the operating system."
678+msgstr ""
679+"Sa wootekaay dañ koo def bamuy yónneel boppam njuumte yi Canonical aki "
680+"farandoom, ñi defar nosteg doxiin gi."
681+
682+#: qml/Wizard/Pages/60-reporting.qml:43
683+msgid ""
684+"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
685+"Privacy</b>"
686+msgstr ""
687+"Man nañ koo dindee ci <b>Jagali Noste</b> ci ronu <b>Karaange &amp; "
688+"Sutura</b>"
689+
690+#: qml/Wizard/Pages/80-finished.qml:24
691+msgid "All done"
692+msgstr "Sotti na"
693+
694+#: qml/Wizard/Pages/80-finished.qml:39
695+msgid "Nice work!"
696+msgstr "Liggéey bu rafet!"
697+
698+#: qml/Wizard/Pages/80-finished.qml:46
699+msgid "Your phone is now ready to use."
700+msgstr "Leegi sa wootekaay noppi na ngir ñu man koo jëfandikoo."
701+
702+#: qml/Wizard/Pages/80-finished.qml:53
703+msgid "Finish"
704+msgstr "Jeexal"
705+
706+#. Translators: This is the arrow for "Back" buttons
707+#: qml/Wizard/StackButton.qml:39
708+#, qt-format
709+msgid "〈 %1"
710+msgstr "〈 %1"
711+
712+#. Translators: This is the arrow for "Forward" buttons
713+#: qml/Wizard/StackButton.qml:42
714+#, qt-format
715+msgid "%1 〉"
716+msgstr "%1 〉"
717+
718+#~ msgid "Log out"
719+#~ msgstr "Génn"
720+
721+#~ msgid "Power"
722+#~ msgstr "Fay"
723+
724+#~ msgid "Reboot"
725+#~ msgstr "Fay-taalaat"
726+
727+#~ msgid "Shut down"
728+#~ msgstr "Fay"
729+
730+#~ msgid "Restart"
731+#~ msgstr "Fay-taalaat"
732+
733+#~ msgid "Power off"
734+#~ msgstr "Fay"
735+
736+#~ msgid "Try swiping from the top edge to access the indicators"
737+#~ msgstr "Jéemal diri tambale ci kaw ngir gis wonekaay yi"
738+
739+#~ msgid "Top edge"
740+#~ msgstr "Cat wu kaw"
741+
742+#~ msgid "Close"
743+#~ msgstr "Tëj"
744+
745+#~ msgid "Swipe up again to close the settings screen"
746+#~ msgstr "Diriwaatal ci kaw ngir tëj xoolu jekkal yi"
747+
748+#~ msgid "Left edge"
749+#~ msgstr "Catu cammoñ"
750+
751+#~ msgid "Well done"
752+#~ msgstr "Jaa-jëf"
753+
754+#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
755+#~ msgstr ""
756+#~ "Jéemal diri tambalee ci cammoñ ngir gis ubbikaay bi ngir àgg gu gaaw ci "
757+#~ "jëfekaay yi"
758+
759+#~ msgid "Skip intro"
760+#~ msgstr "Tëb ndoorteel"
761+
762+#~ msgid "Try swiping from the right edge to unlock the phone"
763+#~ msgstr "Jéemal diri tambalee ci catu ndijoor bi ngir ubbi wootekaay bi"
764+
765+#~ msgid "Right edge"
766+#~ msgstr "Cat wu ndijoor"
767+
768+#~ msgid "Settings"
769+#~ msgstr "Jekkal"
770+
771+#~ msgid ""
772+#~ "You have now mastered the edge gestures and can start using the "
773+#~ "phone<br><br>Tap on the screen to start"
774+#~ msgstr ""
775+#~ "Léegi nàng nga bu baax kon man nga tàmbali jëfandikoo wootekaay bi <br><br> "
776+#~ "Bësal ci xoolu bi ngir tàmbali"
777+
778+#~ msgid "Store"
779+#~ msgstr "Ja"
780+
781+#~ msgid "Search"
782+#~ msgstr "Seet"
783+
784+#~ msgid "Type or say a command"
785+#~ msgstr "Bind walla wax ag cantaane"
786+
787+#~ msgid "Loading. Please Wait..."
788+#~ msgstr "Yeb. Di ñaan nga xaar..."
789+
790+#~ msgid "Speaking..."
791+#~ msgstr "Maa ngi wax..."
792+
793+#~ msgid "Speak Now..."
794+#~ msgstr "Léegi waxal..."
795+
796+#~ msgid "Confirm"
797+#~ msgstr "Dëggal"
798+
799+#~ msgid "Please re-enter"
800+#~ msgstr "Di la ñaan nga duggalaat"
qml/Components/Background.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Utils 0.1 as Utils
2020
2121Loader {
qml/Components/BaseCarouselDelegate.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/*!
2121 \brief Base delegate for use with the Carousel component
qml/Components/Carousel.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "carousel.js" as CarouselJS
2020
2121/*! The Carousel component presents the items of a model in a carousel view. It's similar to a
qml/Components/Circle.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Rectangle {
2020 antialiasing: true
qml/Components/DelayedLockscreen.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121Item {
qml/Components/Dialogs.qml+5−4
@@ -14,12 +14,13 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919import Unity.Application 0.1
2020import Unity.Session 0.1
21−import Ubuntu.Components 1.1
2221import GlobalShortcut 1.0
22+import Ubuntu.Components 1.3
23+import Unity.Platform 1.0
2324import "../Greeter"
2425
2526Item {
@@ -46,13 +47,13 @@ Item {
4647
4748 GlobalShortcut { // reboot/shutdown dialog
4849 shortcut: Qt.Key_PowerDown
49− active: root.usageScenario === "desktop"
50+ active: Platform.isPC
5051 onTriggered: root.unitySessionService.RequestShutdown()
5152 }
5253
5354 GlobalShortcut { // reboot/shutdown dialog
5455 shortcut: Qt.Key_PowerOff
55− active: root.usageScenario === "desktop"
56+ active: Platform.isPC
5657 onTriggered: root.unitySessionService.RequestShutdown()
5758 }
5859
qml/Components/DragHandle.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020
2121/*
qml/Components/DraggingArea.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020MouseArea {
2121 id: draggingArea
qml/Components/EdgeDragEvaluator.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020
2121/*
qml/Components/Header.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import Ubuntu.Components 1.1
18−import Ubuntu.Components.Themes.Ambiance 1.1
17+import Ubuntu.Components 1.3
18+import Ubuntu.Components.Themes.Ambiance 1.3
1919
2020PageHeadStyle {
2121 id: root
qml/Components/InputMethod.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Unity.Application 0.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Ubuntu.Gestures 0.1
2121
2222Item {
qml/Components/LazyImage.qml+24−13
@@ -17,8 +17,8 @@
1717 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1818 */
1919
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
20+import QtQuick 2.4
21+import Ubuntu.Components 1.3
2222
2323Item {
2424 id: root
@@ -31,13 +31,12 @@ Item {
3131 property real initialHeight: scaleTo == "height" || scaleTo == "fit" ? height : units.gu(10)
3232
3333 property alias sourceSize: image.sourceSize
34− property alias fillMode: image.fillMode
3534 property alias asynchronous: image.asynchronous
3635 property alias cache: image.cache
37− property alias horizontalAlignment: image.horizontalAlignment
38− property alias verticalAlignment: image.verticalAlignment
3936 property alias sourceImage: image
40− property alias borderSource: shape.borderSource
37+
38+ property bool useUbuntuShape: true
39+ property bool pressed: false
4140
4241 state: "default"
4342
@@ -50,12 +49,15 @@ Item {
5049 }
5150 }
5251
53− UbuntuShape {
52+ Loader {
5453 id: placeholder
5554 objectName: "placeholder"
56− color: "#22FFFFFF"
5755 anchors.fill: shape
56+ active: useUbuntuShape
5857 visible: opacity != 0
58+ sourceComponent: UbuntuShape {
59+ backgroundColor: "#22FFFFFF"
60+ }
5961
6062 ActivityIndicator {
6163 id: activity
@@ -78,28 +80,37 @@ Item {
7880 }
7981 }
8082
81− UbuntuShape {
83+ Loader {
8284 id: shape
8385 objectName: "shape"
8486 height: root.initialHeight
8587 width: root.initialWidth
8688 anchors.centerIn: root.scaleTo == "fit" ? parent : undefined
87−
89+ active: useUbuntuShape
8890 opacity: 0
8991 visible: opacity != 0
92+ sourceComponent: UbuntuShapeOverlay {
93+ property bool pressed: false
94+ overlayColor: Qt.rgba(0, 0, 0, pressed ? 0.1 : 0)
95+ overlayRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
96+ }
97+ onLoaded: {
98+ item.source = image;
99+ item.pressed = Qt.binding(function() { return root.pressed; });
100+ }
90101
91− image: Image {
102+ Image {
92103 id: image
93104 objectName: "image"
94105
95106 property url nextSource
96107 property string format: image.implicitWidth > image.implicitHeight ? "landscape" : "portrait"
97108
109+ anchors.fill: parent
110+ visible: !useUbuntuShape
98111 fillMode: Image.PreserveAspectFit
99112 asynchronous: true
100113 cache: false
101− horizontalAlignment: Image.AlignHCenter
102− verticalAlignment: Image.AlignVCenter
103114 sourceSize.width: root.scaleTo == "width" ? root.width
104115 : root.scaleTo == "fit" && root.width <= root.height ? root.width
105116 : 0
qml/Components/ListItems/Header.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020
2121Item {
2222 property alias text: label.text
qml/Components/ListItems/ThinDivider.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Image {
2020 anchors {
qml/Components/ListViewOSKScroller.qmlnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import "../Components"
19+
20+Item {
21+ id: root
22+
23+ property ListView list
24+
25+ Binding {
26+ target: list
27+ property: "bottomMargin"
28+ value: d.bottomMargin
29+ }
30+
31+ function setMakeSureVisibleItem(item) {
32+ d.previousVisibleHeight = d.visibleHeight;
33+ d.makeSureVisibleItem = item;
34+ }
35+
36+ QtObject {
37+ id: d
38+ property var makeSureVisibleItem
39+ property real previousVisibleHeight: 0
40+ readonly property real visibleHeight: list.height - list.bottomMargin
41+ readonly property real bottomMargin: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
42+
43+ onVisibleHeightChanged: {
44+ if (makeSureVisibleItem && makeSureVisibleItem.activeFocus && previousVisibleHeight > visibleHeight) {
45+ var textAreaPos = makeSureVisibleItem.mapToItem(list, 0, 0);
46+ if (textAreaPos.y + makeSureVisibleItem.height > visibleHeight) {
47+ list.contentY += textAreaPos.y + makeSureVisibleItem.height - visibleHeight
48+ }
49+ }
50+ previousVisibleHeight = visibleHeight;
51+ }
52+ }
53+}
qml/Components/Lockscreen.qml+3−3
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.0
19−import Ubuntu.Components.Popups 1.0
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.Popups 1.3
2020import Ubuntu.Telephony 0.1 as Telephony
2121
2222Showable {
qml/Components/NotificationAudio.qmlnew file+42
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+
19+Item {
20+ id: root
21+ property string source: ""
22+ readonly property var playbackState: priv.audio ? priv.audio.playbackState : 0
23+
24+ function play() {
25+ priv.audio.play();
26+ }
27+ function stop() {
28+ priv.audio.stop();
29+ }
30+
31+ QtObject {
32+ id: priv
33+ property var audio: {
34+ try {
35+ return Qt.createQmlObject("import QtMultimedia 5.6; Audio { source: root.source; audioRole: MediaPlayer.NotificationRole }", priv)
36+ } catch(err) {
37+ console.log("Upstream audioRole enum not available, falling back to old role name.");
38+ return Qt.createQmlObject("import QtMultimedia 5.0; Audio { source: root.source; audioRole: MediaPlayer.alert }", priv)
39+ }
40+ }
41+ }
42+}
qml/Components/Orientations.qmlnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+
19+QtObject {
20+ id: root
21+
22+ // Just because "native" is a reserved keyword :(
23+ property int native_: Qt.PortraitOrientation
24+
25+ property int primary: Qt.PortraitOrientation
26+
27+ property int landscape: Qt.LandscapeOrientation
28+ property int invertedLandscape: Qt.InvertedLandscapeOrientation
29+ property int portrait: Qt.PortraitOrientation
30+ property int invertedPortrait: Qt.InvertedPortraitOrientation
31+
32+ function map(orientations) {
33+ var result = 0;
34+
35+ if (orientations & Qt.PortraitOrientation) {
36+ result |= root.portrait;
37+ }
38+
39+ if (orientations & Qt.InvertedPortraitOrientation) {
40+ result |= root.invertedPortrait;
41+ }
42+
43+ if (orientations & Qt.LandscapeOrientation) {
44+ result |= root.landscape;
45+ }
46+
47+ if (orientations & Qt.InvertedLandscapeOrientation) {
48+ result |= root.invertedLandscape;
49+ }
50+
51+ if (result == 0) {
52+ result = root.primary;
53+ }
54+
55+ return result;
56+ }
57+}
qml/Components/PanelState/PanelState.qml+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717pragma Singleton
18−import QtQuick 2.0
18+import QtQuick 2.4
1919
2020QtObject {
2121 id: root
qml/Components/PassphraseLockscreen.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121Item {
qml/Components/PhysicalKeysMapper.qml+14−21
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Powerd 0.1
1919
2020/*!
@@ -57,27 +57,20 @@ Item {
5757
5858 property bool altPressed: false
5959 property bool altTabPressed: false
60− }
6160
62− Timer {
63− id: powerKeyLongPressTimer
64− interval: root.powerKeyLongPressTime
65− onTriggered: root.powerKeyLongPressed();
61+ property var powerButtonPressStart: 0
6662 }
6763
68− function onKeyPressed(event) {
69− if ((event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff)
70− && (!event.isAutoRepeat || !powerKeyLongPressTimer.running)) {
71−
72− // FIXME: We only consider power key presses if the screen is
73− // on because of bugs 1410830/1409003. The theory is that when
74− // those bugs are encountered, there is a >2s delay between the
75− // power press event and the power release event, which causes
76− // the shutdown dialog to appear on resume. So to avoid that
77− // symptom while we investigate the root cause, we simply won't
78− // initiate any dialogs when the screen is off.
79− if (Powerd.status === Powerd.On) {
80− powerKeyLongPressTimer.restart();
64+ function onKeyPressed(event, currentEventTimestamp) {
65+ if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
66+ if (event.isAutoRepeat) {
67+ if (d.powerButtonPressStart > 0
68+ && currentEventTimestamp - d.powerButtonPressStart >= powerKeyLongPressTime) {
69+ d.powerButtonPressStart = 0;
70+ root.powerKeyLongPressed();
71+ }
72+ } else {
73+ d.powerButtonPressStart = currentEventTimestamp;
8174 }
8275 } else if ((event.key == Qt.Key_MediaTogglePlayPause || event.key == Qt.Key_MediaPlay) && !event.isAutoRepeat) {
8376 event.accepted = callManager.handleMediaKey(false);
@@ -113,9 +106,9 @@ Item {
113106 }
114107 }
115108
116− function onKeyReleased(event) {
109+ function onKeyReleased(event, currentEventTimestamp) {
117110 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
118− powerKeyLongPressTimer.stop();
111+ d.powerButtonPressStart = 0;
119112 event.accepted = true;
120113 } else if (event.key == Qt.Key_VolumeDown) {
121114 if (!d.ignoreVolumeEvents) root.volumeDownTriggered();
qml/Components/PinLockscreen.qml+3−3
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import Ubuntu.Components.ListItems 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3
2020import "../Components"
2121
2222Item {
qml/Components/PinPadButton.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020AbstractButton {
2121 id: root
qml/Components/Rating.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/*! Rating widget bar. */
2121
qml/Components/RatingStyle.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Row {
2121 anchors.fill: parent
qml/Components/ResponsiveGridView.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/*
2121 Essentially a GridView where you can specify the maximum number of columns it can have.
qml/Components/ResponsiveVerticalJournal.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020import Dash 0.1
2121
qml/Components/ScreenGrabber.qml+6−5
@@ -14,8 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import QtMultimedia 5.0
17+import QtQuick 2.4
1918import ScreenGrabber 0.1
2019import GlobalShortcut 1.0
2120
@@ -26,6 +25,9 @@ Rectangle {
2625 anchors.fill: parent
2726 opacity: 0.0
2827
28+ // to be set from outside
29+ property int rotationAngle: 0
30+
2931 ScreenGrabber {
3032 id: screenGrabber
3133 objectName: "screenGrabber"
@@ -37,9 +39,8 @@ Rectangle {
3739 onTriggered: capture()
3840 }
3941
40− Audio {
42+ NotificationAudio {
4143 id: shutterSound
42− audioRole: MediaPlayer.alert
4344 source: "/system/media/audio/ui/camera_click.ogg"
4445 }
4546
@@ -67,7 +68,7 @@ Rectangle {
6768 to: 0.0
6869 onStopped: {
6970 if (visible) {
70− screenGrabber.captureAndSave();
71+ screenGrabber.captureAndSave(root.rotationAngle);
7172 visible = false;
7273 }
7374 }
qml/Components/ScrollCalculator.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: scrollArea
qml/Components/SearchHistoryModel/SearchHistoryModel.qml+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717pragma Singleton
18−import QtQuick 2.0
18+import QtQuick 2.4
1919
2020// TODO sanitize input, move to persistent storage
2121
qml/Components/ShellDialog.qml+3−3
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
19−import Ubuntu.Components 1.1
20−import Ubuntu.Components.Popups 0.1
19+import Ubuntu.Components 1.3
20+import Ubuntu.Components.Popups 1.3
2121
2222/*
2323 A Dialog configured for use as a proper in-scene Dialog
qml/Components/Showable.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Item {
2020 id: showable
qml/Components/StandardAnimation.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919NumberAnimation {
2020 duration: 200
qml/Components/UbuntuShapeForItem.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/* FIXME: This component is duplicating the UbuntuShape from the SDK, but shapes more
2121 * general (Item-based) components. This ability should be incorporated into the SDK's
qml/Components/Unity8Settings.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import GSettings 1.0
1919
2020QtObject {
qml/Components/UnityInputInfo/UnityInputInfo.qml+2−2
@@ -16,10 +16,10 @@
1616
1717pragma Singleton
1818
19−import QtQuick 2.3
19+import QtQuick 2.4
2020import Unity.InputInfo 0.1
2121// Workaround https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1473471
22−import Ubuntu.Components 1.2
22+import Ubuntu.Components 1.3
2323
2424Item {
2525 id: root
qml/Components/WallpaperResolver.qmlnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import AccountsService 0.1
19+import GSettings 1.0
20+import Ubuntu.Components 1.3
21+
22+/*
23+ Defines the background URL based on several factors, such as:
24+ - default, fallback, background
25+ - Background set in AccountSettings, if any
26+ - Background set in GSettings, if any
27+ */
28+QtObject {
29+ // Users should set their UI width here.
30+ property real width
31+
32+ property url defaultBackground: Qt.resolvedUrl(width >= units.gu(60) ? "../graphics/tablet_background.jpg"
33+ : "../graphics/phone_background.jpg")
34+
35+ // That's the property users of this component are going to consume.
36+ readonly property url background: asImageTester.status == Image.Ready ? asImageTester.source
37+ : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
38+
39+ // This is a dummy image to detect if the custom AS set wallpaper loads successfully.
40+ property var _asImageTester: Image {
41+ id: asImageTester
42+ source: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : ""
43+ height: 0
44+ width: 0
45+ sourceSize.height: 0
46+ sourceSize.width: 0
47+ }
48+
49+ // This is a dummy image to detect if the custom GSettings set wallpaper loads successfully.
50+ property var _gsImageTester: Image {
51+ id: gsImageTester
52+ source: backgroundSettings.pictureUri && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : ""
53+ height: 0
54+ width: 0
55+ sourceSize.height: 0
56+ sourceSize.width: 0
57+ }
58+
59+ property var _gsettings: GSettings {
60+ id: backgroundSettings
61+ schema.id: "org.gnome.desktop.background"
62+ }
63+}
qml/Components/WindowControlButtons.qml+5−2
@@ -16,8 +16,8 @@
1616 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
1717 */
1818
19−import QtQuick 2.3
20−import Ubuntu.Components 1.1
19+import QtQuick 2.4
20+import Ubuntu.Components 1.3
2121
2222Row {
2323 id: root
@@ -28,6 +28,7 @@ Row {
2828 signal maximize()
2929
3030 Rectangle {
31+ objectName: "closeWindowButton"
3132 height: parent.height; width: height; radius: height / 2
3233 gradient: Gradient {
3334 GradientStop { color: "#F49073"; position: 0 }
@@ -38,6 +39,7 @@ Row {
3839 MouseArea { anchors.fill: parent; onClicked: root.close() }
3940 }
4041 Rectangle {
42+ objectName: "minimizeWindowButton"
4143 height: parent.height; width: height; radius: height / 2
4244 gradient: Gradient {
4345 GradientStop { color: "#92918C"; position: 0 }
@@ -48,6 +50,7 @@ Row {
4850 MouseArea { anchors.fill: parent; onClicked: root.minimize() }
4951 }
5052 Rectangle {
53+ objectName: "maximizeWindowButton"
5154 height: parent.height; width: height; radius: height / 2
5255 gradient: Gradient {
5356 GradientStop { color: "#92918C"; position: 0 }
qml/Components/WindowScreenshot.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818
1919Item {
2020 id: root
qml/Components/WrongPasswordAnimation.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919SequentialAnimation {
2020 id: root
qml/Components/ZoomableImage.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121/*! \brief Zoomable for image.
qml/Dash/CardCarousel.qml+3−3
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121DashRenderer {
@@ -68,7 +68,7 @@ DashRenderer {
6868 item.fontScale = Qt.binding(function() { return carousel.fontScale; });
6969 item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
7070 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
71− item.artShapeBorderSource = "none";
71+ item.artShapeStyle = "flat";
7272 item.scopeStyle = cardCarousel.scopeStyle;
7373 }
7474
qml/Dash/CardGrid.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "../Components"
1919
2020DashRenderer {
qml/Dash/CardHorizontalList.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121DashRenderer {
qml/Dash/CardTool.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020/*!
qml/Dash/CardVerticalJournal.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121DashRenderer {
qml/Dash/Dash.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import Unity 0.2
2121import Utils 0.1
qml/Dash/DashApplication.qml+4−3
@@ -14,15 +14,16 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.0
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
2020
2121MainView {
2222 implicitWidth: units.gu(40)
2323 implicitHeight: units.gu(68)
2424
25− useDeprecatedToolbar: false
25+ // Workaround bug #1475643
26+ headerColor: Qt.rgba(0, 0, 0, 0)
2627
2728 Dash {
2829 anchors.fill: parent
qml/Dash/DashBackground.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Image {
2020 source: anchors.fill.width > anchors.fill.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png"
qml/Dash/DashCategoryBase.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 width: parent.width
qml/Dash/DashContent.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Unity 0.2
2020import Utils 0.1
2121import "../Components"
qml/Dash/DashContentTabBarStyle.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import Ubuntu.Components.Themes.Ambiance 0.1
17+import Ubuntu.Components.Themes.Ambiance 1.3
1818
1919TabBarStyle {
2020 indicatorImageSource: "graphics/tabbarchevron.png"
qml/Dash/DashNavigation.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Dash 0.1
2020import "../Components"
2121
@@ -48,7 +48,7 @@ Item {
4848 id: d
4949 readonly property color foregroundColor: root.scopeStyle
5050 ? root.scopeStyle.getTextColor(backgroundItem.luminance)
51− : Theme.palette.normal.baseText
51+ : theme.palette.normal.baseText
5252 readonly property bool bothVisible: altNavigationButton.visible && navigationButton.visible
5353 readonly property real navigationWidth: root.width >= units.gu(60) ? units.gu(40) : root.width
5454 readonly property real buttonWidth: navigationWidth / (bothVisible ? 2 : 1)
qml/Dash/DashNavigationButton.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020AbstractButton {
2121 id: root
@@ -24,7 +24,7 @@ AbstractButton {
2424 // Set by parent
2525 property var scope: null
2626 property var scopeStyle: null
27− property color foregroundColor: Theme.palette.normal.baseText
27+ property color foregroundColor: theme.palette.normal.baseText
2828 property bool isAltNavigation: false
2929 property bool showDivider: false
3030
qml/Dash/DashNavigationList.qml+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.ListItems 0.1 as ListItem
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItem
2020import "../Components"
2121
2222Item {
@@ -24,7 +24,7 @@ Item {
2424 property var navigation: null
2525 property var currentNavigation: null
2626 property var scopeStyle: null
27− property color foregroundColor: Theme.palette.normal.baseText
27+ property color foregroundColor: theme.palette.normal.baseText
2828 signal enterNavigation(var newNavigationId, bool hasChildren)
2929 signal goBackToParentClicked()
3030 signal allNavigationClicked()
qml/Dash/PageHeader.qml → qml/Dash/DashPageHeader.qmlrenamed+12−16
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.Themes.Ambiance 1.1
20−import Ubuntu.Components.Popups 1.0
21−import Ubuntu.Components.ListItems 1.0
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.Themes.Ambiance 1.3
20+import Ubuntu.Components.Popups 1.3
21+import Ubuntu.Components.ListItems 1.3
2222import "../Components"
2323import "../Components/SearchHistoryModel"
2424
@@ -136,7 +136,7 @@ Item {
136136 objectName: "headerContainer"
137137 clip: contentY < height
138138 anchors { left: parent.left; top: parent.top; right: parent.right }
139− height: units.gu(7)
139+ height: header.contentHeight
140140 contentHeight: headersColumn.height
141141 interactive: false
142142 contentY: showSearch ? 0 : height
@@ -171,18 +171,15 @@ Item {
171171 PageHeadStyle {
172172 id: searchHeader
173173 anchors { left: parent.left; right: parent.right }
174− height: headerContainer.height
175− contentHeight: height
176174 opacity: headerContainer.clip || headerContainer.showSearch ? 1 : 0 // setting visible false cause column to relayout
177175 __separator_visible: false
178176 // Required to keep PageHeadStyle noise down as it expects the Page's properties around.
179177 property var styledItem: searchHeader
180− property string title
181178 property color dividerColor: "transparent" // Doesn't matter as we don't have PageHeadSections
182179 property color panelColor: background.topColor
183180 panelForegroundColor: config.foregroundColor
184− property var config: PageHeadConfiguration {
185− foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : Theme.palette.normal.baseText
181+ config: PageHeadConfiguration {
182+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : theme.palette.normal.baseText
186183 backAction: Action {
187184 iconName: "back"
188185 onTriggered: {
@@ -247,16 +244,15 @@ Item {
247244 objectName: "innerPageHeader"
248245 anchors { left: parent.left; right: parent.right }
249246 height: headerContainer.height
250− contentHeight: height
251247 opacity: headerContainer.clip || !headerContainer.showSearch ? 1 : 0 // setting visible false cause column to relayout
252248 __separator_visible: false
253249 property var styledItem: header
254− property string title: root.title
255250 property color dividerColor: "transparent" // Doesn't matter as we don't have PageHeadSections
256251 property color panelColor: background.topColor
257252 panelForegroundColor: config.foregroundColor
258− property var config: PageHeadConfiguration {
259− foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : Theme.palette.normal.baseText
253+ config: PageHeadConfiguration {
254+ title: root.title
255+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : theme.palette.normal.baseText
260256 backAction: Action {
261257 iconName: backIsClose ? "close" : "back"
262258 visible: root.showBackButton
qml/Dash/DashRenderer.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Item {
2020 property real collapsedHeight
qml/Dash/GenericScopeView.qml+6−6
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Utils 0.1
2020import Unity 0.2
2121import Dash 0.1
@@ -573,7 +573,7 @@ FocusScope {
573573 }
574574 fontSize: "small"
575575 font.weight: Font.Bold
576− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
576+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
577577 }
578578 }
579579
@@ -610,7 +610,7 @@ FocusScope {
610610 width: categoryView.width
611611 height: section != "" ? units.gu(5) : 0
612612 text: section
613− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
613+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
614614 iconName: delegate && delegate.headerLink ? "go-next" : ""
615615 onClicked: {
616616 if (delegate.headerLink) scopeView.scope.performQuery(delegate.headerLink);
@@ -624,7 +624,7 @@ FocusScope {
624624 sourceComponent: scopeView.showPageHeader ? pageHeaderComponent : undefined
625625 Component {
626626 id: pageHeaderComponent
627− PageHeader {
627+ DashPageHeader {
628628 objectName: "scopePageHeader"
629629 width: parent.width
630630 title: scopeView.scope ? scopeView.scope.name : ""
@@ -731,7 +731,7 @@ FocusScope {
731731 }
732732 fontSize: "small"
733733 font.weight: Font.Bold
734− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
734+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
735735 }
736736
737737 Connections {
qml/Dash/PreviewListView.qml+3−3
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Unity 0.2
2020import "../Components"
2121import "Previews" as Previews
@@ -43,7 +43,7 @@ Item {
4343
4444 signal backClicked()
4545
46− PageHeader {
46+ DashPageHeader {
4747 id: header
4848 objectName: "pageHeader"
4949 width: parent.width
qml/Dash/Previews/Preview.qml+13−20
@@ -14,8 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import "../../Components"
1920
2021/*! \brief This component constructs the Preview UI.
2122 *
@@ -72,18 +73,10 @@ Item {
7273 }
7374 width: row.columnWidth
7475 spacing: row.spacing
75− bottomMargin: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
76− property var makeSureVisibleItem
77− property real previousVisibleHeight: 0
78− property real visibleHeight: height - bottomMargin
79− onVisibleHeightChanged: {
80− if (makeSureVisibleItem && makeSureVisibleItem.activeFocus && previousVisibleHeight > visibleHeight) {
81− var textAreaPos = makeSureVisibleItem.mapToItem(column, 0, 0);
82− if (textAreaPos.y + makeSureVisibleItem.height > column.visibleHeight) {
83− column.contentY += textAreaPos.y + makeSureVisibleItem.height - column.visibleHeight
84− }
85− }
86− previousVisibleHeight = visibleHeight;
76+
77+ ListViewOSKScroller {
78+ id: oskScroller
79+ list: column
8780 }
8881
8982 model: columnModel
@@ -100,17 +93,17 @@ Item {
10093 anchors {
10194 left: parent.left
10295 right: parent.right
103− leftMargin: units.gu(1)
104− rightMargin: units.gu(1)
96+ leftMargin: widgetMargins
97+ rightMargin: widgetMargins
10598 }
10699
107100 onTriggered: {
108101 previewModel.triggered(widgetId, actionId, data);
109102 }
110− onMakeSureVisible: {
111− column.previousVisibleHeight=column.visibleHeight
112− column.makeSureVisibleItem=item
113− }
103+
104+ onMakeSureVisible: {
105+ oskScroller.setMakeSureVisibleItem(item);
106+ }
114107
115108 onFocusChanged: if (focus) column.positionViewAtIndex(index, ListView.Contain)
116109
qml/Dash/Previews/PreviewActionButton.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Button {
2121 signal triggeredAction(var actionData)
qml/Dash/Previews/PreviewActionCombo.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: root
@@ -33,7 +33,7 @@ Item {
3333
3434 objectName: "moreLessButton"
3535 text: !expanded ? i18n.tr("More...") : i18n.tr("Less...")
36− strokeColor: Theme.palette.normal.baseText
36+ strokeColor: theme.palette.normal.baseText
3737 onClicked: expanded = !expanded
3838 width: parent.width
3939 }
qml/Dash/Previews/PreviewActions.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/*! This preview widget shows either one button, two buttons or one button
2121 * and a combo button depending on the number of items in widgetData["actions"].
@@ -50,7 +50,7 @@ PreviewWidget {
5050 Binding {
5151 target: loader.item
5252 property: "strokeColor"
53− value: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
53+ value: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
5454 }
5555 Connections {
5656 target: loader.item
qml/Dash/Previews/PreviewAudioPlayback.qml+7−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtMultimedia 5.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020
2121/*! \brief Preview widget for audio tracks.
2222
@@ -139,7 +139,7 @@ PreviewWidget {
139139 objectName: "trackTitleLabel"
140140 anchors { top: parent.top; left: parent.left; right: parent.right }
141141 opacity: 0.9
142− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
142+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
143143 fontSize: "small"
144144 horizontalAlignment: Text.AlignLeft
145145 text: modelData["title"]
@@ -152,7 +152,7 @@ PreviewWidget {
152152 anchors { top: trackTitleLabel.bottom; left: parent.left; right: parent.right }
153153 visible: text !== ""
154154 opacity: 0.9
155− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
155+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
156156 font.weight: Font.Light
157157 fontSize: "small"
158158 horizontalAlignment: Text.AlignLeft
@@ -175,7 +175,7 @@ PreviewWidget {
175175 }
176176 height: units.dp(2)
177177 visible: progressBarImage.visible
178− color: UbuntuColors.orange
178+ backgroundColor: UbuntuColors.orange
179179 }
180180
181181 Image {
@@ -193,7 +193,7 @@ PreviewWidget {
193193 anchors.verticalCenter: parent.verticalCenter
194194 width: parent.column3Width
195195 opacity: 0.9
196− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
196+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
197197 fontSize: "small"
198198 horizontalAlignment: Text.AlignRight
199199 text: audio.lengthToString(modelData["length"])
qml/Dash/Previews/PreviewComment.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.2
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/*! \brief Preview widget for comments.
2121
qml/Dash/Previews/PreviewCommentInput.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! \brief Preview widget for commenting.
qml/Dash/Previews/PreviewExpandable.qml+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! \brief Preview widget for expandable widgets.
@@ -41,7 +41,7 @@ PreviewWidget {
4141 right: expandButton.left
4242 }
4343 fontSize: "large"
44− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
44+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
4545 visible: text !== ""
4646 opacity: .8
4747 text: widgetData["title"] || ""
@@ -62,7 +62,7 @@ PreviewWidget {
6262 width: units.gu(3)
6363 height: units.gu(3)
6464 name: root.expanded ? "view-collapse" : "view-expand"
65− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
65+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
6666 }
6767 }
6868
qml/Dash/Previews/PreviewHeader.qml+10−10
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Dash 0.1
2020import "../"
2121
@@ -40,10 +40,10 @@ PreviewWidget {
4040 readonly property string title: root.widgetData["title"] || ""
4141 readonly property string subtitle: root.widgetData["subtitle"] || ""
4242 readonly property var attributes: root.widgetData["attributes"] || null
43− readonly property color fontColor: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
43+ readonly property color fontColor: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
4444
4545 // Rewire the source since we may have unwired it on onStatusChanged
46− onMascotChanged: if (mascotShapeLoader.item) mascotShapeLoader.item.image.source = mascot;
46+ onMascotChanged: if (mascotShapeLoader.item) mascotShapeLoader.item.source.source = mascot;
4747
4848 implicitHeight: row.height + row.margins * 2
4949 width: parent.width
@@ -77,16 +77,16 @@ PreviewWidget {
7777
7878 sourceComponent: UbuntuShape {
7979 objectName: "mascotShape"
80− visible: image.status === Image.Ready
81− image: Image {
80+ visible: source.status === Image.Ready
81+ sourceFillMode: UbuntuShape.PreserveAspectCrop
82+ sourceHorizontalAlignment: UbuntuShape.AlignHCenter
83+ sourceVerticalAlignment: UbuntuShape.AlignVCenter
84+ source: Image {
8285 source: headerRoot.mascot
8386 width: source ? mascotShapeLoader.width : 0
8487 height: mascotShapeLoader.height
8588
8689 sourceSize { width: mascotShapeLoader.maxSize; height: mascotShapeLoader.maxSize }
87− fillMode: Image.PreserveAspectCrop
88− horizontalAlignment: Image.AlignHCenter
89− verticalAlignment: Image.AlignVCenter
9090 onStatusChanged: if (status === Image.Error) source = headerRoot.fallback;
9191 }
9292 }
qml/Dash/Previews/PreviewIconActions.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/*! This preview widget icons+label for number of items in widgetData["actions"].
2121 * For each of the items we recognize the fields "label", "icon", "temporaryIcon" and "id".
qml/Dash/Previews/PreviewImageGallery.qml+3−3
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! This preview widget shows a horizontal list of images.
@@ -62,7 +62,7 @@ PreviewWidget {
6262 source: modelData ? modelData : ""
6363 scaleTo: "height"
6464 initialWidth: units.gu(13)
65− borderSource: mouseArea.pressed ? "radius_pressed.sci" : "radius_idle.sci"
65+ pressed: mouseArea.pressed
6666
6767 MouseArea {
6868 id: mouseArea
qml/Dash/Previews/PreviewMediaToolbar.qmlnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import "../../Components"
20+
21+Rectangle {
22+ property alias shareData: sharingWidget.shareData
23+
24+ implicitHeight: units.gu(6)
25+ color: Qt.rgba(0, 0, 0, 0.8)
26+ visible: sharingWidget.visible
27+
28+ PreviewSharing {
29+ id: sharingWidget
30+ anchors {
31+ left: parent.left
32+ verticalCenter: parent.verticalCenter
33+ leftMargin: units.gu(1)
34+ }
35+ }
36+}
qml/Dash/Previews/PreviewOverlay.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121Rectangle {
@@ -158,7 +158,7 @@ Rectangle {
158158 anchors.centerIn: parent
159159 width: units.gu(2.5)
160160 height: width
161− color: Theme.palette.normal.foregroundText
161+ color: theme.palette.normal.foregroundText
162162 name: "close"
163163 }
164164 }
qml/Dash/Previews/PreviewPayments.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Payments 0.1
2020
2121/*! \brief Preview widget for a purchase button.
qml/Dash/Previews/PreviewProgress.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.DownloadDaemonListener 0.1
2020
2121/*! \brief Preview widget for a progress bar.
qml/Dash/Previews/PreviewRatingDisplay.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! \brief Preview widget for rating display.
@@ -60,7 +60,7 @@ PreviewWidget {
6060 urlIconEmpty: widgetData["rating-icon-empty"]
6161 urlIconFull: widgetData["rating-icon-full"]
6262 urlIconHalf: widgetData["rating-icon-half"]
63− labelColor: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
63+ labelColor: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
6464 }
6565 }
6666 }
qml/Dash/Previews/PreviewRatingEdit.qml+2−2
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.4
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! \brief Preview widget for editable rating.
@@ -56,7 +56,7 @@ PreviewWidget {
5656 urlIconEmpty: widgetData["rating-icon-empty"]
5757 urlIconFull: widgetData["rating-icon-full"]
5858 urlIconHalf: widgetData["rating-icon-half"]
59− labelColor: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
59+ labelColor: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
6060 }
6161
6262 PreviewRatingInput {
qml/Dash/Previews/PreviewRatingInput.qml+6−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! \brief Preview widget for rating.
@@ -79,7 +79,7 @@ PreviewWidget {
7979 verticalCenter: parent.verticalCenter
8080 left: parent.left
8181 }
82− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
82+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
8383 opacity: .8
8484 text: widgetData["rating-label"] || i18n.tr("Rate this")
8585 }
@@ -124,7 +124,7 @@ PreviewWidget {
124124 left: parent.left
125125 right: parent.right
126126 }
127− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
127+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
128128 opacity: .8
129129 text: widgetData["review-label"] || i18n.tr("Add a review")
130130 }
@@ -170,7 +170,7 @@ PreviewWidget {
170170 top: parent.top
171171 right: parent.right
172172 }
173− color: readyToSubmit ? Theme.palette.selected.base : Theme.palette.normal.base
173+ color: readyToSubmit ? theme.palette.selected.base : theme.palette.normal.base
174174 text: widgetData["submit-label"] || i18n.tr("Send")
175175 onClicked: {
176176 if (readyToSubmit) root.submit()
qml/Dash/Previews/PreviewRatingSingleDisplay.qml+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717import QtQuick 2.4
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121Column {
qml/Dash/Previews/PreviewSharing.qmlnew file+105
@@ -0,0 +1,105 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Content 1.1
20+
21+Item {
22+ id: root
23+ implicitHeight: button.height
24+ implicitWidth: button.width
25+
26+ property var shareData
27+ readonly property bool isUrlExternal: url && url.indexOf("file:///") != 0 && url.indexOf("/") != 0
28+ readonly property string contentType: shareData ? shareData["contentType"] : ""
29+ readonly property var url: shareData ? shareData["uri"] : ""
30+ readonly property Item rootItem: QuickUtils.rootItem(root)
31+
32+ visible: url != ""
33+
34+ AbstractButton {
35+ id: button
36+ height: units.gu(4)
37+ width: units.gu(4)
38+ onClicked: peerPicker.visible = true
39+
40+ Icon {
41+ anchors.centerIn: parent
42+ height: units.gu(3)
43+ width: units.gu(3)
44+ source: "image://theme/share"
45+ }
46+ }
47+
48+ Component {
49+ id: exportItemComponent
50+ ContentItem {
51+ name: i18n.tr("Preview Share Item")
52+ }
53+ }
54+
55+ Component {
56+ id: contentPeerComponent
57+ ContentPeerPicker {
58+ handler: ContentHandler.Share
59+ contentType: {
60+ // for now, treat all external urls as Links, or it will break contenthub
61+ if (root.isUrlExternal) return ContentType.Links;
62+
63+ switch(root.contentType) {
64+ case "all": return ContentType.All;
65+ case "contacts": return ContentType.Contacts;
66+ case "documents": return ContentType.Documents;
67+ case "links": return ContentType.Links;
68+ case "music": return ContentType.Music;
69+ case "pictures": return ContentType.Pictures;
70+ case "text": return ContentType.Text;
71+ default:
72+ case "unknown": return ContentType.Unknown;
73+ case "videos": return ContentType.Videos;
74+ }
75+ }
76+
77+ onPeerSelected: {
78+ var transfer = peer.request();
79+ if (transfer.state === ContentTransfer.InProgress) {
80+ var items = new Array();
81+ for (var i = 0; i < url.length; i++) {
82+ var exportItem = exportItemComponent.createObject();
83+ exportItem.url = url[i];
84+ items.push(exportItem);
85+ }
86+ transfer.items = items;
87+ transfer.state = ContentTransfer.Charged;
88+ }
89+ peerPicker.visible = false;
90+ }
91+ onCancelPressed: peerPicker.visible = false;
92+ }
93+ }
94+
95+ Loader {
96+ id: peerPicker
97+ objectName: "peerPicker"
98+ parent: rootItem
99+ anchors.fill: parent
100+ visible: false
101+ active: root.visible
102+
103+ sourceComponent: contentPeerComponent
104+ }
105+}
qml/Dash/Previews/PreviewTable.qml+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../Components"
2121
2222/*! \brief Preview widget for table.
@@ -48,7 +48,7 @@ PreviewWidget {
4848 }
4949 height: visible ? implicitHeight : 0
5050 fontSize: "large"
51− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
51+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
5252 visible: text !== ""
5353 opacity: .8
5454 text: widgetData["title"] || ""
@@ -72,7 +72,7 @@ PreviewWidget {
7272 fontSize: "small"
7373 text: perRowRepeater.model[index]
7474 visible: root.expanded || rowIndex < maximumCollapsedRowCount
75− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
75+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
7676 font.bold: index == 0
7777 wrapMode: Text.Wrap
7878 Layout.alignment: Qt.AlignTop
qml/Dash/Previews/PreviewTextSummary.qml+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! \brief Preview widget for text.
@@ -39,7 +39,7 @@ PreviewWidget {
3939 }
4040 height: visible ? implicitHeight : 0
4141 fontSize: "large"
42− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
42+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
4343 visible: text !== ""
4444 opacity: .8
4545 text: widgetData["title"] || ""
@@ -61,7 +61,7 @@ PreviewWidget {
6161 clip: true
6262 fontSize: "small"
6363 lineHeight: 1.2
64− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
64+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText
6565 opacity: .8
6666 text: widgetData["text"] || ""
6767 wrapMode: Text.Wrap
qml/Dash/Previews/PreviewVideoPlayback.qml+15−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Thumbnailer 0.1
2020import "../../Components"
2121
@@ -30,6 +30,8 @@ PreviewWidget {
3030 implicitWidth: units.gu(35)
3131 implicitHeight: childrenRect.height
3232
33+ widgetMargins: -units.gu(1)
34+
3335 LazyImage {
3436 objectName: "screenshot"
3537 anchors {
@@ -51,6 +53,7 @@ PreviewWidget {
5153 return "";
5254 }
5355 initialHeight: width * 10 / 16
56+ useUbuntuShape: false
5457
5558 Image {
5659 objectName: "playButton"
@@ -70,5 +73,15 @@ PreviewWidget {
7073 anchors.fill: parent
7174 onClicked: Qt.openUrlExternally(widgetData["source"])
7275 }
76+
77+ PreviewMediaToolbar {
78+ id: toolbar
79+ anchors {
80+ left: parent.left
81+ right: parent.right
82+ bottom: parent.bottom
83+ }
84+ shareData: widgetData["shareData"]
85+ }
7386 }
7487}
qml/Dash/Previews/PreviewWidget.qml+4−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919/*! Interface for preview widgets. */
2020
@@ -34,6 +34,9 @@ Item {
3434 //! Should the widget show in expanded mode (For those that support it)
3535 property bool expanded: true
3636
37+ //! Set margins width.
38+ property real widgetMargins: units.gu(1)
39+
3740 /*! \brief This signal should be emitted when a preview action was triggered.
3841 *
3942 * \param widgetId, actionId Respective identifiers from widgetData.
qml/Dash/Previews/PreviewWidgetFactory.qml+4−1
@@ -15,7 +15,7 @@
1515 *
1616 */
1717
18−import QtQuick 2.0
18+import QtQuick 2.4
1919
2020//! \brief This component loads the widgets based on widgetData["type"].
2121
@@ -40,6 +40,9 @@ Loader {
4040 //! Set to true if the parent preview is displayed.
4141 property bool isCurrentPreview: false
4242
43+ //! Set margins width.
44+ property real widgetMargins: status === Loader.Ready ? item.widgetMargins : units.gu(1)
45+
4346 //! Triggered signal forwarded from the widgets.
4447 signal triggered(string widgetId, string actionId, var data)
4548
qml/Dash/Previews/PreviewZoomableImage.qml+21−9
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../Components"
2020
2121/*! \brief Preview widget for image.
@@ -27,7 +27,10 @@ import "../../Components"
2727
2828PreviewWidget {
2929 id: root
30− implicitHeight: units.gu(22)
30+ implicitWidth: units.gu(35)
31+ implicitHeight: lazyImage.height
32+
33+ widgetMargins: -units.gu(1)
3134
3235 property Item rootItem: QuickUtils.rootItem(root)
3336
@@ -35,15 +38,14 @@ PreviewWidget {
3538 id: lazyImage
3639 objectName: "lazyImage"
3740 anchors {
38− top: parent.top
39− bottom: parent.bottom
40− horizontalCenter: parent.horizontalCenter
41+ left: parent.left
42+ right: parent.right
4143 }
42− scaleTo: "height"
44+ scaleTo: "width"
4345 source: widgetData["source"]
4446 asynchronous: true
45−
46− borderSource: mouseArea.pressed ? "radius_pressed.sci" : "radius_idle.sci"
47+ useUbuntuShape: false
48+ pressed: mouseArea.pressed
4749
4850 MouseArea {
4951 id: mouseArea
@@ -62,6 +64,16 @@ PreviewWidget {
6264 // But at the moment the model never changes
6365 onStatusChanged: if (lazyImage.sourceImage.status === Image.Error) lazyImage.sourceImage.source = widgetData["fallback"];
6466 }
67+
68+ PreviewMediaToolbar {
69+ id: toolbar
70+ anchors {
71+ left: parent.left
72+ right: parent.right
73+ bottom: parent.bottom
74+ }
75+ shareData: widgetData["shareData"]
76+ }
6577 }
6678
6779 PreviewOverlay {
qml/Dash/PullToRefreshScopeStyle.qml+3−3
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.Styles 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.Styles 1.3
2020
2121/**
2222 * TODO: Once the SDK version of PullToRefreshStyle doesn't have bug 1375799
qml/Dash/ScopeListView.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020ListViewWithPageHeader {
qml/Dash/ScopeSettings/ScopeSetting.qml+11−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020/*! Interface for settings widgets. */
2121
@@ -32,6 +32,15 @@ Item {
3232 */
3333 signal updated(var value)
3434
35+ /*! \brief This signal should be emitted when widget gains the focus
36+ * and input method popups.
37+ * And preview widget should reposition in visible area to avoid
38+ * keyboard appears over the widget.
39+ *
40+ * \param item, id of specified item which is needed to reposition.
41+ */
42+ signal makeSureVisible(var item)
43+
3544 //! \internal
3645 readonly property real settingMargins: units.gu(2)
3746}
qml/Dash/ScopeSettings/ScopeSettingBoolean.qml+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.ListItems 1.0 as ListItem
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItem
2020
2121ScopeSetting {
2222 id: root
@@ -44,7 +44,7 @@ ScopeSetting {
4444 elide: Text.ElideMiddle
4545 maximumLineCount: 2
4646 wrapMode: Text.Wrap
47− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
47+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
4848 }
4949
5050 CheckBox {
qml/Dash/ScopeSettings/ScopeSettingList.qml+3−3
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.ListItems 1.0 as ListItem
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItem
2020
2121ScopeSetting {
2222 id: root
qml/Dash/ScopeSettings/ScopeSettingNumber.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818
1919ScopeSettingString {
2020 mode: "number"
qml/Dash/ScopeSettings/ScopeSettingString.qml+12−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.ListItems 1.0 as ListItem
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItem
2020
2121ScopeSetting {
2222 id: root
@@ -44,7 +44,7 @@ ScopeSetting {
4444 elide: Text.ElideMiddle
4545 maximumLineCount: 2
4646 wrapMode: Text.Wrap
47− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
47+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
4848 }
4949
5050 TextField {
@@ -57,7 +57,7 @@ ScopeSetting {
5757 }
5858 width: root.mode == "number" ? units.gu(8) : units.gu(12)
5959 text: widgetData.value
60− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.fieldText
60+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.fieldText
6161 validator: root.mode == "number" ? doubleValidator : null
6262 hasClearButton: root.mode == "number" ? false : true
6363
@@ -78,6 +78,12 @@ ScopeSetting {
7878 updateText();
7979 }
8080 }
81+
82+ readonly property bool inputMethodVisible: Qt.inputMethod.visible
83+ onInputMethodVisibleChanged: {
84+ if(inputMethodVisible && activeFocus)
85+ root.makeSureVisible(control);
86+ }
8187 }
8288 }
8389}
qml/Dash/ScopeSettings/ScopeSettingsWidgetFactory.qml+5−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818
1919//! \brief This component loads the widgets based on type.
2020
@@ -30,6 +30,9 @@ Loader {
3030 //! Triggered signal forwarded from the widgets.
3131 signal updated(var value)
3232
33+ //! makeSureVisible signal forwarded from the widgets.
34+ signal makeSureVisible(var item)
35+
3336 source: widgetSource
3437
3538 //! \cond private
@@ -53,5 +56,6 @@ Loader {
5356 Connections {
5457 target: root.item
5558 onUpdated: if (value !== widgetData.value) root.updated(value)
59+ onMakeSureVisible: root.makeSureVisible(item)
5660 }
5761}
qml/Dash/ScopeSettingsPage.qml+12−3
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Unity 0.2
2020import "../Components"
2121import "ScopeSettings"
@@ -28,7 +28,7 @@ Item {
2828
2929 signal backClicked()
3030
31− PageHeader {
31+ DashPageHeader {
3232 id: header
3333 objectName: "pageHeader"
3434 width: parent.width
@@ -51,6 +51,11 @@ Item {
5151 model: root.scope ? root.scope.settings : null
5252 clip: true
5353
54+ ListViewOSKScroller {
55+ id: oskScroller
56+ list: scopeSettings
57+ }
58+
5459 delegate: ScopeSettingsWidgetFactory {
5560 objectName: "scopeSettingItem" + index
5661 width: root.width
@@ -58,6 +63,10 @@ Item {
5863 scopeStyle: root.scopeStyle
5964
6065 onUpdated: model.value = value;
66+
67+ onMakeSureVisible: { // var item
68+ oskScroller.setMakeSureVisibleItem(item);
69+ }
6170 }
6271 }
6372}
qml/Dash/ScopesList.qml+2−2
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Item {
@@ -61,7 +61,7 @@ Item {
6161 value: root.scope ? root.scope.searchQuery : ""
6262 }
6363
64− PageHeader {
64+ DashPageHeader {
6565 id: header
6666 objectName: "pageHeader"
6767 title: i18n.tr("Manage")
qml/Dash/ScopesListCategory.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Dash 0.1
2020import "../Components/ListItems" as ListItems
2121
@@ -43,7 +43,7 @@ Item {
4343 id: header
4444 width: root.width
4545 height: units.gu(5)
46− color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
46+ color: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
4747 }
4848
4949 readonly property double listItemHeight: units.gu(6)
qml/Dash/ScopesListCategoryItem.qml+4−4
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020
2121MouseArea {
2222 id: root
@@ -49,10 +49,10 @@ MouseArea {
4949 width: units.gu(5)
5050 height: units.gu(5)
5151 visible: !hideChildren
52− image: Image {
52+ sourceFillMode: UbuntuShape.PreserveAspectCrop
53+ source: Image {
5354 id: shapeImage
5455 cache: true
55− fillMode: Image.PreserveAspectCrop
5656 sourceSize { width: shape.width; height: shape.height }
5757 }
5858 }
qml/DeviceConfiguration.qml+87−64
@@ -14,80 +14,103 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
19−StateGroup {
19+QtObject {
2020 id: root
2121
2222 readonly property int useNativeOrientation: -1
2323
24− property int primaryOrientation: useNativeOrientation
24+ // The only writable property in the API
25+ // all other properties are set according to the device name
26+ property alias name: priv.state
2527
26− property int supportedOrientations: Qt.PortraitOrientation
27− | Qt.InvertedPortraitOrientation
28− | Qt.LandscapeOrientation
29− | Qt.InvertedLandscapeOrientation
28+ readonly property alias primaryOrientation: priv.primaryOrientation
29+ readonly property alias supportedOrientations: priv.supportedOrientations
30+ readonly property alias landscapeOrientation: priv.landscapeOrientation
31+ readonly property alias invertedLandscapeOrientation: priv.invertedLandscapeOrientation
32+ readonly property alias portraitOrientation: priv.portraitOrientation
33+ readonly property alias invertedPortraitOrientation: priv.invertedPortraitOrientation
3034
31− // Supported values so far:
32− // "phone", "tablet" or "desktop"
33− property string category: "phone"
35+ readonly property alias category: priv.category
3436
35− property int ignoredMice: 0
37+ readonly property alias ignoredMice: priv.ignoredMice
3638
39+ readonly property var priv: StateGroup {
40+ id: priv
3741
38− property alias name: root.state
42+ property int primaryOrientation: root.useNativeOrientation
3943
40− states: [
41− State {
42− name: "mako"
43− PropertyChanges {
44− target: root
45− supportedOrientations: Qt.PortraitOrientation
46− | Qt.LandscapeOrientation
47− | Qt.InvertedLandscapeOrientation
48− }
49− },
50− State {
51− name: "krillin"
52− PropertyChanges {
53− target: root
54− supportedOrientations: Qt.PortraitOrientation
55− | Qt.LandscapeOrientation
56− | Qt.InvertedLandscapeOrientation
57− }
58− },
59− State {
60− name: "arale"
61− PropertyChanges {
62− target: root
63− supportedOrientations: Qt.PortraitOrientation
64− | Qt.LandscapeOrientation
65− | Qt.InvertedLandscapeOrientation
66− ignoredMice: 1
67− }
68− },
69− State {
70− name: "manta"
71− PropertyChanges {
72− target: root
73− category: "tablet"
74− }
75− },
76− State {
77− name: "flo"
78− PropertyChanges {
79− target: root
80− primaryOrientation: Qt.InvertedLandscapeOrientation
81− category: "tablet"
82− }
83− },
84− State {
85− name: "desktop"
86− PropertyChanges {
87− target: root
88− category: "desktop"
89− }
90− }
91− ]
44+ property int supportedOrientations: Qt.PortraitOrientation
45+ | Qt.InvertedPortraitOrientation
46+ | Qt.LandscapeOrientation
47+ | Qt.InvertedLandscapeOrientation
48+
49+ property int landscapeOrientation: Qt.LandscapeOrientation
50+ property int invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
51+ property int portraitOrientation: Qt.PortraitOrientation
52+ property int invertedPortraitOrientation: Qt.InvertedPortraitOrientation
53+
54+ // Supported values so far:
55+ // "phone", "tablet" or "desktop"
56+ property string category: "phone"
9257
58+ property int ignoredMice: 0
59+
60+ states: [
61+ State {
62+ name: "mako"
63+ PropertyChanges {
64+ target: priv
65+ supportedOrientations: Qt.PortraitOrientation
66+ | Qt.LandscapeOrientation
67+ | Qt.InvertedLandscapeOrientation
68+ }
69+ },
70+ State {
71+ name: "krillin"
72+ PropertyChanges {
73+ target: priv
74+ supportedOrientations: Qt.PortraitOrientation
75+ | Qt.LandscapeOrientation
76+ | Qt.InvertedLandscapeOrientation
77+ }
78+ },
79+ State {
80+ name: "arale"
81+ PropertyChanges {
82+ target: priv
83+ supportedOrientations: Qt.PortraitOrientation
84+ | Qt.LandscapeOrientation
85+ | Qt.InvertedLandscapeOrientation
86+ ignoredMice: 1
87+ }
88+ },
89+ State {
90+ name: "manta"
91+ PropertyChanges {
92+ target: priv
93+ category: "tablet"
94+ }
95+ },
96+ State {
97+ name: "flo"
98+ PropertyChanges {
99+ target: priv
100+ landscapeOrientation: Qt.InvertedLandscapeOrientation
101+ invertedLandscapeOrientation: Qt.LandscapeOrientation
102+ primaryOrientation: Qt.InvertedLandscapeOrientation
103+ category: "tablet"
104+ }
105+ },
106+ State {
107+ name: "desktop"
108+ PropertyChanges {
109+ target: priv
110+ category: "desktop"
111+ supportedOrientations: root.useNativeOrientation
112+ }
113+ }
114+ ]
115+ }
93116}
qml/DisabledScreenNotice.qmlnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import "Components"
20+
21+Image {
22+ id: root
23+
24+ WallpaperResolver {
25+ width: root.width
26+ id: wallpaperResolver
27+ }
28+
29+ source: wallpaperResolver.background
30+
31+ UbuntuShape {
32+ anchors.fill: text
33+ anchors.margins: -units.gu(2)
34+ backgroundColor: "black"
35+ opacity: 0.4
36+ }
37+
38+ Label {
39+ id: text
40+ anchors.centerIn: parent
41+ width: parent.width / 2
42+ text: i18n.tr("Your device is now connected to an external display.")
43+ color: "white"
44+ horizontalAlignment: Text.AlignHCenter
45+ verticalAlignment: Text.AlignVCenter
46+ fontSize: "x-large"
47+ wrapMode: Text.Wrap
48+ }
49+}
qml/Greeter/Clock.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Panel/Indicators"
2020import Unity.Indicators 0.1 as Indicators
2121
qml/Greeter/CoverPage.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import "../Components"
2121
qml/Greeter/Dot.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Image {
2020 states: [
qml/Greeter/Greeter.qml+3−3
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import AccountsService 0.1
1919import GSettings 1.0
20−import Ubuntu.Components 1.1
20+import Ubuntu.Components 1.3
2121import Ubuntu.SystemImage 0.1
2222import Unity.Launcher 0.1
2323import "../Components"
@@ -251,7 +251,7 @@ Showable {
251251
252252 // event eater
253253 // Nothing should leak to items behind the greeter
254− MouseArea { anchors.fill: parent }
254+ MouseArea { anchors.fill: parent; hoverEnabled: true }
255255
256256 Loader {
257257 id: loader
qml/Greeter/Infographics.qml+2−2
@@ -16,8 +16,8 @@
1616
1717import "../Components"
1818import "Gradient.js" as Gradient
19−import QtQuick 2.0
20−import Ubuntu.Components 0.1
19+import QtQuick 2.4
20+import Ubuntu.Components 1.3
2121
2222Item {
2323 id: infographic
qml/Greeter/IntegratedLightDMImpl.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import IntegratedLightDM 0.1 as LightDM
1919
2020Item{
qml/Greeter/LightDM.qml+1−1
@@ -19,7 +19,7 @@
1919 * plugin
2020 */
2121
22−import QtQuick 2.3
22+import QtQuick 2.4
2323
2424Loader {
2525 id: loader
qml/Greeter/LoginList.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121Item {
qml/Greeter/NarrowView.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121FocusScope {
qml/Greeter/ObjectPositioner.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 property int count
qml/Greeter/ShimGreeter.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818
1919/*
2020 * This is a shim greeter that is only used to provide a shell,
qml/Greeter/WideView.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020FocusScope {
2121 id: root
qml/Launcher/FoldingLauncherDelegate.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020LauncherDelegate {
2121 id: root
qml/Launcher/Launcher.qml+3−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "../Components"
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Ubuntu.Gestures 0.1
2121import Unity.Launcher 0.1
2222
@@ -188,6 +188,7 @@ Item {
188188 bottom: parent.bottom
189189 }
190190 enabled: root.shadeBackground && root.state == "visible"
191+ visible: enabled // otherwise it will get in the way of cursor selection for some reason
191192 onPressed: {
192193 root.state = ""
193194 }
qml/Launcher/LauncherDelegate.qml+7−8
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: root
@@ -130,13 +130,12 @@ Item {
130130 anchors.fill: parent
131131 anchors.margins: units.gu(1)
132132 radius: "medium"
133− borderSource: "none"
134−
135− image: Image {
133+ aspect: UbuntuShape.Flat
134+ sourceFillMode: UbuntuShape.PreserveAspectCrop
135+ source: Image {
136136 id: iconImage
137137 sourceSize.width: iconShape.width
138138 sourceSize.height: iconShape.height
139− fillMode: Image.PreserveAspectCrop
140139 source: root.iconName
141140 }
142141 }
@@ -159,9 +158,9 @@ Item {
159158 }
160159 width: Math.min(root.itemWidth, Math.max(units.gu(2), countLabel.implicitWidth + units.gu(1)))
161160 height: units.gu(2)
162− color: UbuntuColors.orange
161+ backgroundColor: UbuntuColors.orange
163162 visible: root.countVisible
164− borderSource: "none"
163+ aspect: UbuntuShape.Flat
165164
166165 Label {
167166 id: countLabel
qml/Launcher/LauncherPanel.qml+6−6
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.2
19−import Ubuntu.Components.ListItems 1.0 as ListItems
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItems
2020import Unity.Launcher 0.1
21−import Ubuntu.Components.Popups 0.1
21+import Ubuntu.Components.Popups 1.3
2222import "../Components/ListItems"
2323import "../Components/"
2424
@@ -61,8 +61,8 @@ Rectangle {
6161 fill: parent
6262 topMargin: -units.gu(2)
6363 }
64− borderSource: "none"
65− color: UbuntuColors.orange
64+ aspect: UbuntuShape.Flat
65+ backgroundColor: UbuntuColors.orange
6666 }
6767
6868 Image {
qml/Notifications/Notification.qml+16−15
@@ -14,14 +14,14 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import QtMultimedia 5.0
17+import QtQuick 2.4
1918import Powerd 0.1
20−import Ubuntu.Components 1.2
19+import Ubuntu.Components 1.3
20+import Ubuntu.Components.ListItems 1.3 as ListItem
2121import Unity.Notifications 1.0
2222import QMenuModel 0.1
2323import Utils 0.1
24−import Ubuntu.Components.ListItems 0.1 as ListItem
24+import "../Components"
2525
2626Item {
2727 id: notification
@@ -50,6 +50,7 @@ Item {
5050 readonly property real contentSpacing: units.gu(2)
5151 readonly property bool canBeClosed: type === Notification.Ephemeral
5252 property bool hasMouse
53+ property url background: ""
5354
5455 objectName: "background"
5556 implicitHeight: type !== Notification.PlaceHolder ? (fullscreen ? maxHeight : outterColumn.height - shapedBack.anchors.topMargin + contentSpacing * 2) : 0
@@ -79,10 +80,9 @@ Item {
7980 return result;
8081 }
8182
82− Audio {
83+ NotificationAudio {
8384 id: sound
8485 objectName: "sound"
85− audioRole: MediaPlayer.alert
8686 source: hints["suppress-sound"] !== "true" && hints["sound-file"] !== undefined ? hints["sound-file"] : ""
8787 }
8888
@@ -152,10 +152,10 @@ Item {
152152 rightMargin: notification.margins
153153 topMargin: type === Notification.Confirmation ? units.gu(.5) : 0
154154 }
155− color: parent.color
155+ backgroundColor: parent.color
156156 opacity: parent.opacity
157157 radius: "medium"
158− borderSource: "none"
158+ aspect: UbuntuShape.Flat
159159 }
160160
161161 Rectangle {
@@ -281,7 +281,7 @@ Item {
281281 }
282282 visible: type !== Notification.Confirmation
283283 fontSize: "medium"
284− color: darkOnBright ? sdFontColor : Theme.palette.selected.backgroundText
284+ color: darkOnBright ? sdFontColor : theme.palette.selected.backgroundText
285285 elide: Text.ElideRight
286286 textFormat: Text.PlainText
287287 }
@@ -296,7 +296,7 @@ Item {
296296 }
297297 visible: body != "" && type !== Notification.Confirmation
298298 fontSize: "small"
299− color: darkOnBright ? sdFontColor : Theme.palette.selected.backgroundText
299+ color: darkOnBright ? sdFontColor : theme.palette.selected.backgroundText
300300 wrapMode: Text.WordWrap
301301 maximumLineCount: type == Notification.SnapDecision ? 12 : 2
302302 elide: Text.ElideRight
@@ -337,7 +337,7 @@ Item {
337337 anchors.horizontalCenter: parent.horizontalCenter
338338 visible: type === Notification.Confirmation && body !== ""
339339 fontSize: "medium"
340− color: darkOnBright ? sdFontColor : Theme.palette.selected.backgroundText
340+ color: darkOnBright ? sdFontColor : theme.palette.selected.backgroundText
341341 wrapMode: Text.WordWrap
342342 maximumLineCount: 1
343343 elide: Text.ElideRight
@@ -357,8 +357,8 @@ Item {
357357 }
358358
359359 height: units.gu(1)
360− color: darkOnBright ? UbuntuColors.darkGrey : UbuntuColors.lightGrey
361− borderSource: "none"
360+ backgroundColor: darkOnBright ? UbuntuColors.darkGrey : UbuntuColors.lightGrey
361+ aspect: UbuntuShape.Flat
362362 radius: "small"
363363
364364 UbuntuShape {
@@ -366,8 +366,8 @@ Item {
366366 objectName: "innerBar"
367367 width: valueIndicator.width * valueIndicator.value / 100
368368 height: units.gu(1)
369− color: notification.hints["x-canonical-value-bar-tint"] === "true" ? UbuntuColors.orange : darkOnBright ? UbuntuColors.lightGrey : "white"
370− borderSource: "none"
369+ backgroundColor: notification.hints["x-canonical-value-bar-tint"] === "true" ? UbuntuColors.orange : darkOnBright ? UbuntuColors.lightGrey : "white"
370+ aspect: UbuntuShape.Flat
371371 radius: "small"
372372 }
373373 }
@@ -401,6 +401,7 @@ Item {
401401 menuData: model
402402 menuIndex: index
403403 maxHeight: notification.maxHeight
404+ background: notification.background
404405
405406 onLoaded: {
406407 notification.fullscreen = Qt.binding(function() { return fullscreen; });
qml/Notifications/NotificationMenuItemFactory.qml+4−3
@@ -17,8 +17,8 @@
1717 * Nick Dedekind <nick.dedekind@canonical.com>
1818 */
1919
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
20+import QtQuick 2.4
21+import Ubuntu.Components 1.3
2222import QMenuModel 0.1
2323import "../Components"
2424
@@ -30,6 +30,7 @@ Loader {
3030 property int menuIndex : -1
3131 property int maxHeight
3232 readonly property bool fullscreen: menuData.type === "com.canonical.snapdecision.pinlock"
33+ property url background: ""
3334
3435 signal accepted()
3536
@@ -149,7 +150,7 @@ Loader {
149150 infoText: notification.summary
150151 errorText: errorAction.valid ? errorAction.state : ""
151152 retryText: notification.body
152− background: shell.background
153+ background: menuFactory.background
153154 darkenBackground: 0.4
154155
155156 onEntered: {
qml/Notifications/Notifications.qml+4−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Unity.Notifications 1.0 as UnityNotifications
2020import Utils 0.1
2121import "../Components"
@@ -29,6 +29,7 @@ ListView {
2929 property real margin
3030 property bool useModal: snapDecisionProxyModel.count > 0
3131 property bool hasMouse
32+ property url background: ""
3233
3334 UnitySortFilterProxyModel {
3435 id: snapDecisionProxyModel
@@ -60,6 +61,7 @@ ListView {
6061 maxHeight: notificationList.height
6162 margins: notificationList.margin
6263 hasMouse: notificationList.hasMouse
64+ background: notificationList.background
6365
6466 // make sure there's no opacity-difference between the several
6567 // elements in a notification
qml/Notifications/OptionToggle.qml+7−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import Ubuntu.Components.ListItems 0.1 as ListItem
20−import Ubuntu.Components.Popups 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItem
20+import Ubuntu.Components.Popups 1.3
2121
2222UbuntuShape {
2323 id: optionToggle
@@ -29,8 +29,8 @@ UbuntuShape {
2929
3030 signal triggered(string id)
3131
32− color: Theme.palette.normal.base
33− borderSource: "none"
32+ backgroundColor: theme.palette.normal.base
33+ aspect: UbuntuShape.Flat
3434 height: expanded ? (optionToggleRepeater.count - startIndex) * itemHeight : itemHeight
3535 width: parent.width
3636 radius: "medium"
qml/Notifications/ShapedIcon.qml+3−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.2
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 property string fileSource
qml/Notifications/SwipeToAct.qml+10−10
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.2
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: swipeToAct
@@ -98,8 +98,8 @@ Item {
9898 id: row
9999 width: parent.width
100100 height: priv.sliderHeight
101− color: priv.sliderBGColor
102− borderSource: "none"
101+ backgroundColor: priv.sliderBGColor
102+ aspect: UbuntuShape.Flat
103103 visible: !clickToAct
104104
105105 UbuntuShape {
@@ -108,8 +108,8 @@ Item {
108108 anchors.top: parent.top
109109 anchors.left: parent.left
110110 anchors.margins: priv.gap
111− color: UbuntuColors.red
112− borderSource: "none"
111+ backgroundColor: UbuntuColors.red
112+ aspect: UbuntuShape.Flat
113113
114114 state: "normal"
115115 height: units.gu(6)
@@ -187,10 +187,10 @@ Item {
187187 }
188188
189189 z: 1
190− color: priv.sliderMainColor
190+ backgroundColor: priv.sliderMainColor
191191 height: units.gu(6)
192192 width: units.gu(6)
193− borderSource: "none"
193+ aspect: UbuntuShape.Flat
194194 radius: "medium"
195195 Icon {
196196 anchors.fill: parent
@@ -226,8 +226,8 @@ Item {
226226 anchors.top: parent.top
227227 anchors.right: parent.right
228228 anchors.margins: priv.gap
229− color: UbuntuColors.green
230− borderSource: "none"
229+ backgroundColor: UbuntuColors.green
230+ aspect: UbuntuShape.Flat
231231
232232 state: "normal"
233233 height: units.gu(6)
qml/OrientedShell.qml+44−25
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import QtQuick.Window 2.0
17+import QtQuick 2.4
18+import QtQuick.Window 2.2
1919import Unity.Session 0.1
2020import GSettings 1.0
2121import "Components"
@@ -23,7 +23,7 @@ import "Components/UnityInputInfo"
2323import "Rotation"
2424// Backup Workaround https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1473471
2525// in case we remove the UnityInputInfo import
26−import Ubuntu.Components 1.2
26+import Ubuntu.Components 1.3
2727
2828Rectangle {
2929 id: root
@@ -32,20 +32,31 @@ Rectangle {
3232 implicitWidth: units.gu(40)
3333 implicitHeight: units.gu(71)
3434
35− // NB: native and primary orientations here don't map exactly to their QScreen counterparts
36− readonly property int nativeOrientation: width > height ? Qt.LandscapeOrientation : Qt.PortraitOrientation
37−
38− readonly property int primaryOrientation:
39− deviceConfiguration.primaryOrientation == deviceConfiguration.useNativeOrientation
40− ? nativeOrientation : deviceConfiguration.primaryOrientation
41−
4235 DeviceConfiguration {
4336 id: deviceConfiguration
4437 name: applicationArguments.deviceName
4538 }
4639
40+ property alias orientations: d.orientations
41+
42+ Item {
43+ id: d
44+
45+ property Orientations orientations: Orientations {
46+ id: orientations
47+ // NB: native and primary orientations here don't map exactly to their QScreen counterparts
48+ native_: root.width > root.height ? Qt.LandscapeOrientation : Qt.PortraitOrientation
49+
50+ primary: deviceConfiguration.primaryOrientation == deviceConfiguration.useNativeOrientation
51+ ? native_ : deviceConfiguration.primaryOrientation
4752
48− // to be overwritten by tests
53+ landscape: deviceConfiguration.landscapeOrientation
54+ invertedLandscape: deviceConfiguration.invertedLandscapeOrientation
55+ portrait: deviceConfiguration.portraitOrientation
56+ invertedPortrait: deviceConfiguration.invertedPortraitOrientation
57+ }
58+ }
59+ // to be overwritten by tests
4960 property var unity8Settings: Unity8Settings {}
5061 property var oskSettings: GSettings { schema.id: "com.canonical.keyboard.maliit" }
5162
@@ -76,6 +87,12 @@ Rectangle {
7687 oskSettings.disableHeight = shell.usageScenario == "desktop"
7788 }
7889
90+ // we must rotate to a supported orientation regardless of shell's preference
91+ property bool orientationChangesEnabled:
92+ (shell.orientation & supportedOrientations) === 0 ? true
93+ : shell.orientationChangesEnabled
94+
95+
7996 Binding {
8097 target: oskSettings
8198 property: "stayHidden"
@@ -89,10 +106,13 @@ Rectangle {
89106 }
90107
91108 readonly property int supportedOrientations: shell.supportedOrientations
92− & deviceConfiguration.supportedOrientations
109+ & (deviceConfiguration.supportedOrientations == deviceConfiguration.useNativeOrientation
110+ ? orientations.native_
111+ : deviceConfiguration.supportedOrientations)
112+
93113 property int acceptedOrientationAngle: {
94114 if (orientation & supportedOrientations) {
95− return Screen.angleBetween(nativeOrientation, orientation);
115+ return Screen.angleBetween(orientations.native_, orientation);
96116 } else if (shell.orientation & supportedOrientations) {
97117 // stay where we are
98118 return shell.orientationAngle;
@@ -102,16 +122,16 @@ Rectangle {
102122 // rotate to some supported orientation as we can't stay where we currently are
103123 // TODO: Choose the closest to the current one
104124 if (supportedOrientations & Qt.PortraitOrientation) {
105− return Screen.angleBetween(nativeOrientation, Qt.PortraitOrientation);
125+ return Screen.angleBetween(orientations.native_, Qt.PortraitOrientation);
106126 } else if (supportedOrientations & Qt.LandscapeOrientation) {
107− return Screen.angleBetween(nativeOrientation, Qt.LandscapeOrientation);
127+ return Screen.angleBetween(orientations.native_, Qt.LandscapeOrientation);
108128 } else if (supportedOrientations & Qt.InvertedPortraitOrientation) {
109− return Screen.angleBetween(nativeOrientation, Qt.InvertedPortraitOrientation);
129+ return Screen.angleBetween(orientations.native_, Qt.InvertedPortraitOrientation);
110130 } else if (supportedOrientations & Qt.InvertedLandscapeOrientation) {
111− return Screen.angleBetween(nativeOrientation, Qt.InvertedLandscapeOrientation);
131+ return Screen.angleBetween(orientations.native_, Qt.InvertedLandscapeOrientation);
112132 } else {
113133 // if all fails, fallback to primary orientation
114− return Screen.angleBetween(nativeOrientation, primaryOrientation);
134+ return Screen.angleBetween(orientations.native_, orientations.primary);
115135 }
116136 }
117137 }
@@ -119,19 +139,19 @@ Rectangle {
119139 function angleToOrientation(angle) {
120140 switch (angle) {
121141 case 0:
122− return nativeOrientation;
142+ return orientations.native_;
123143 case 90:
124− return nativeOrientation === Qt.PortraitOrientation ? Qt.InvertedLandscapeOrientation
144+ return orientations.native_ === Qt.PortraitOrientation ? Qt.InvertedLandscapeOrientation
125145 : Qt.PortraitOrientation;
126146 case 180:
127− return nativeOrientation === Qt.PortraitOrientation ? Qt.InvertedPortraitOrientation
147+ return orientations.native_ === Qt.PortraitOrientation ? Qt.InvertedPortraitOrientation
128148 : Qt.InvertedLandscapeOrientation;
129149 case 270:
130− return nativeOrientation === Qt.PortraitOrientation ? Qt.LandscapeOrientation
150+ return orientations.native_ === Qt.PortraitOrientation ? Qt.LandscapeOrientation
131151 : Qt.InvertedPortraitOrientation;
132152 default:
133153 console.warn("angleToOrientation: Invalid orientation angle: " + angle);
134− return primaryOrientation;
154+ return orientations.primary;
135155 }
136156 }
137157
@@ -150,8 +170,7 @@ Rectangle {
150170 width: root.width
151171 height: root.height
152172 orientation: root.angleToOrientation(orientationAngle)
153− primaryOrientation: root.primaryOrientation
154− nativeOrientation: root.nativeOrientation
173+ orientations: root.orientations
155174 nativeWidth: root.width
156175 nativeHeight: root.height
157176 mode: applicationArguments.mode
qml/Panel/ActiveCallHint.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Telephony 0.1 as Telephony
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Unity.Application 0.1
2121import "../Components"
2222
qml/Panel/Handle.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Rectangle {
2121 id: handle
qml/Panel/IndicatorItem.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Settings.Components 0.1
2020import "Indicators"
2121
qml/Panel/IndicatorItemRow.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: root
qml/Panel/IndicatorPage.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1 as Components
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3 as Components
1919import Unity.Indicators 0.1 as Indicators
2020import "Indicators"
2121
qml/Panel/Indicators/IndicatorBase.qml+1−1
@@ -17,7 +17,7 @@
1717 * Nick Dedekind <nick.dedekind@canonical.com>
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121import Unity.Indicators 0.1
2222
2323Item {
qml/Panel/Indicators/IndicatorDelegate.qml+1−1
@@ -17,7 +17,7 @@
1717 * Nick Dedekind <nick.dedekind@canonical.com>
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121
2222IndicatorBase {
2323 readonly property bool indicatorVisible: rootActionState.indicatorVisible
qml/Panel/Indicators/IndicatorsLight.qml+1−1
@@ -17,7 +17,7 @@
1717 * Renato Araujo Oliveira Filho <renato@canonical.com>
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121import Powerd 0.1
2222import Lights 0.1
2323import QMenuModel 0.1 as QMenuModel
qml/Panel/Indicators/MenuItemFactory.qml+24−20
@@ -14,13 +14,13 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Settings.Menus 0.1 as Menus
1919import Ubuntu.Settings.Components 0.1
2020import QMenuModel 0.1
2121import Utils 0.1 as Utils
22−import Ubuntu.Components.ListItems 0.1 as ListItems
23−import Ubuntu.Components 1.2
22+import Ubuntu.Components.ListItems 1.3 as ListItems
23+import Ubuntu.Components 1.3
2424import Unity.Session 0.1
2525
2626Item {
@@ -249,7 +249,7 @@ Item {
249249 name: "settings"
250250 height: units.gu(3)
251251 width: height
252− color: Theme.palette.selected.backgroundText
252+ color: theme.palette.selected.backgroundText
253253 }
254254 }
255255 }
@@ -281,7 +281,7 @@ Item {
281281 source: menuData.icon
282282 height: units.gu(3)
283283 width: height
284− color: Theme.palette.selected.backgroundText
284+ color: theme.palette.selected.backgroundText
285285 }
286286 }
287287 }
@@ -350,20 +350,23 @@ Item {
350350 id: alarmMenu;
351351
352352 Menus.EventMenu {
353+ id: alarmItem
353354 objectName: "alarmMenu"
354355 property QtObject menuData: null
355356 property var menuModel: menuFactory.menuModel
356357 property int menuIndex: -1
357358 property var extendedData: menuData && menuData.ext || undefined
358− // TODO - bug #1260728
359− property var timeFormatter: Utils.GDateTimeFormatter {
360− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
361− format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
359+
360+ property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
361+ LiveTimer {
362+ frequency: LiveTimer.Relative
363+ relativeTime: alarmItem.serverTime
364+ onTrigger: alarmItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
362365 }
363366
364367 text: menuData && menuData.label || ""
365368 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
366− time: timeFormatter.timeString
369+ time: i18n.relativeDateTime(serverTime)
367370 enabled: menuData && menuData.sensitive || false
368371 highlightWhenPressed: false
369372
@@ -379,8 +382,7 @@ Item {
379382
380383 function loadAttributes() {
381384 if (!menuModel || menuIndex == -1) return;
382− menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
383− 'x-canonical-time-format': 'string'});
385+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64'});
384386 }
385387 }
386388 }
@@ -389,20 +391,23 @@ Item {
389391 id: appointmentMenu;
390392
391393 Menus.EventMenu {
394+ id: appointmentItem
392395 objectName: "appointmentMenu"
393396 property QtObject menuData: null
394397 property var menuModel: menuFactory.menuModel
395398 property int menuIndex: -1
396399 property var extendedData: menuData && menuData.ext || undefined
397− // TODO - bug #1260728
398− property var timeFormatter: Utils.GDateTimeFormatter {
399− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
400− format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
400+
401+ property date serverTime: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
402+ LiveTimer {
403+ frequency: LiveTimer.Relative
404+ relativeTime: appointmentItem.serverTime
405+ onTrigger: appointmentItem.serverTime = new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) * 1000)
401406 }
402407
403408 text: menuData && menuData.label || ""
404409 iconSource: menuData && menuData.icon || "image://theme/calendar"
405− time: timeFormatter.timeString
410+ time: i18n.relativeDateTime(serverTime)
406411 eventColor: getExtendedProperty(extendedData, "xCanonicalColor", Qt.rgba(0.0, 0.0, 0.0, 0.0))
407412 enabled: menuData && menuData.sensitive || false
408413 highlightWhenPressed: false
@@ -420,8 +425,7 @@ Item {
420425 function loadAttributes() {
421426 if (!menuModel || menuIndex == -1) return;
422427 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
423− 'x-canonical-time': 'int64',
424− 'x-canonical-time-format': 'string'});
428+ 'x-canonical-time': 'int64'});
425429 }
426430 }
427431 }
@@ -924,7 +928,7 @@ Item {
924928 enabled: menuData && menuData.sensitive || false
925929 highlightWhenPressed: false
926930 text: menuData && menuData.label || ""
927− foregroundColor: Theme.palette.normal.backgroundText
931+ foregroundColor: theme.palette.normal.backgroundText
928932
929933 onMenuModelChanged: {
930934 loadAttributes();
qml/Panel/Indicators/MessageMenuItemFactory.qml+36−27
@@ -18,8 +18,8 @@
1818 * Olivier Tilloy <olivier.tilloy@canonical.com>
1919 */
2020
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
21+import QtQuick 2.4
22+import Ubuntu.Components 1.3
2323import Ubuntu.Settings.Menus 0.1 as Menus
2424import QMenuModel 0.1 as QMenuModel
2525import Utils 0.1 as Utils
@@ -35,12 +35,17 @@ Loader {
3535 signal menuSelected
3636 signal menuDeselected
3737
38− property var extendedData: menuData && menuData.ext || undefined
39− property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
40−
41− // TODO - bug #1260728
42− property var timeFormatter: Utils.RelativeTimeFormatter {
43− time: getExtendedProperty(extendedData, "xCanonicalTime", 0) / 1000000
38+ QtObject {
39+ id: priv
40+ property var extendedData: menuData && menuData.ext || undefined
41+ property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
42+ property date time: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) / 1000)
43+ property string timeString: i18n.relativeDateTime(time)
44+ }
45+ LiveTimer {
46+ frequency: LiveTimer.Relative
47+ relativeTime: priv.time
48+ onTrigger: priv.timeString = Qt.binding(function() { return i18n.relativeDateTime(priv.time); })
4449 }
4550
4651 onMenuModelChanged: {
@@ -50,7 +55,7 @@ Loader {
5055 loadAttributes();
5156 }
5257
53− sourceComponent: loadMessage(actionsDescription)
58+ sourceComponent: loadMessage(priv.actionsDescription)
5459
5560 function loadMessage(actions)
5661 {
@@ -100,11 +105,11 @@ Loader {
100105 objectName: "simpleTextMessage"
101106 // text
102107 title: menuData && menuData.label || ""
103− time: timeFormatter.timeString
104− body: getExtendedProperty(extendedData, "xCanonicalText", "")
108+ time: priv.timeString
109+ body: getExtendedProperty(priv.extendedData, "xCanonicalText", "")
105110 // icons
106− avatar: getExtendedProperty(extendedData, "icon", "image://theme/contact")
107− icon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "image://theme/message")
111+ avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
112+ icon: getExtendedProperty(priv.extendedData, "xCanonicalAppIcon", "image://theme/message")
108113 // actions
109114 enabled: menuData && menuData.sensitive || false
110115 removable: !selected
@@ -133,7 +138,9 @@ Loader {
133138 Menus.TextMessageMenu {
134139 id: message
135140 objectName: "textMessage"
136− property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
141+ property var replyActionDescription: priv.actionsDescription && priv.actionsDescription.length > 0 ?
142+ priv.actionsDescription[0] :
143+ undefined
137144
138145 property var replyAction: QMenuModel.UnityMenuAction {
139146 model: menuModel
@@ -143,13 +150,13 @@ Loader {
143150
144151 // text
145152 title: menuData && menuData.label || ""
146− time: timeFormatter.timeString
147− body: getExtendedProperty(extendedData, "xCanonicalText", "")
148− replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.tr("Send"))
153+ time: priv.timeString
154+ body: getExtendedProperty(priv.extendedData, "xCanonicalText", "")
155+ replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.ctr("Button: Send a reply message", "Send"))
149156 replyHintText: i18n.ctr("Label: Hint in message indicator line edit", "Reply")
150157 // icons
151− avatar: getExtendedProperty(extendedData, "icon", "image://theme/contact")
152− icon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "image://theme/message")
158+ avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
159+ icon: getExtendedProperty(priv.extendedData, "xCanonicalAppIcon", "image://theme/message")
153160 // actions
154161 replyEnabled: replyAction.valid && replyAction.enabled
155162 enabled: menuData && menuData.sensitive || false
@@ -183,8 +190,10 @@ Loader {
183190 Menus.SnapDecisionMenu {
184191 id: message
185192 objectName: "snapDecision"
186− property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
187− property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
193+ property var activateActionDescription: priv.actionsDescription && priv.actionsDescription.length > 0 ?
194+ priv.actionsDescription[0] : undefined
195+ property var replyActionDescription: priv.actionsDescription && priv.actionsDescription.length > 1 ?
196+ priv.actionsDescription[1] : undefined
188197
189198 property var activateAction: QMenuModel.UnityMenuAction {
190199 model: menuModel
@@ -199,13 +208,13 @@ Loader {
199208
200209 // text
201210 title: menuData && menuData.label || ""
202− time: timeFormatter.timeString
203− body: getExtendedProperty(extendedData, "xCanonicalText", "")
204− actionButtonText: getExtendedProperty(activateActionDescription, "label", i18n.tr("Call back"))
205− replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.tr("Send"))
211+ time: priv.timeString
212+ body: getExtendedProperty(priv.extendedData, "xCanonicalText", "")
213+ actionButtonText: getExtendedProperty(activateActionDescription, "label", i18n.ctr("Button: Call back on phone", "Call back"))
214+ replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.ctr("Button: Send a reply message", "Send"))
206215 // icons
207− avatar: getExtendedProperty(extendedData, "icon", "image://theme/contact")
208− icon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "image://theme/missed-call")
216+ avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
217+ icon: getExtendedProperty(priv.extendedData, "xCanonicalAppIcon", "image://theme/missed-call")
209218 // actions
210219 actionEnabled: activateAction.valid && activateAction.enabled
211220 replyEnabled: replyAction.valid && replyAction.enabled
qml/Panel/Indicators/ModemInfoItem.qml+6−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 0.1
20−import Ubuntu.Components.ListItems 0.1 as ListItem
19+import Ubuntu.Components 1.3
20+import Ubuntu.Components.ListItems 1.3 as ListItem
2121
2222ListItem.Empty {
2323 id: menu
@@ -65,7 +65,7 @@ ListItem.Empty {
6565 height: parent.height
6666 Icon {
6767 id: statusIcon
68− color: Theme.palette.selected.backgroundText
68+ color: theme.palette.selected.backgroundText
6969
7070 Layout.preferredHeight: parent.height
7171 Layout.preferredWidth: Layout.preferredHeight
@@ -75,7 +75,7 @@ ListItem.Empty {
7575
7676 Icon {
7777 id: iconConnectivity
78− color: Theme.palette.selected.backgroundText
78+ color: theme.palette.selected.backgroundText
7979
8080 Layout.preferredHeight: parent.height
8181 Layout.preferredWidth: Layout.preferredHeight
qml/Panel/Indicators/RoamingIndication.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020
2121RowLayout {
2222 spacing: units.gu(0.5)
@@ -30,7 +30,7 @@ RowLayout {
3030
3131 Icon {
3232 id: iconRoaming
33− color: Theme.palette.selected.backgroundText
33+ color: theme.palette.selected.backgroundText
3434
3535 Layout.preferredHeight: parent.height
3636 Layout.preferredWidth: Layout.preferredHeight
qml/Panel/Indicators/client/IndicatorRepresentation.qml+3−3
@@ -18,9 +18,9 @@
1818 * Nick Dedekind <nick.dedekind@canonical.com>
1919 */
2020
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Ubuntu.Components.ListItems 0.1 as ListItem
21+import QtQuick 2.4
22+import Ubuntu.Components 1.3
23+import Ubuntu.Components.ListItems 1.3 as ListItem
2424import "../.."
2525
2626Page {
qml/Panel/Indicators/client/IndicatorsClient.qml+4−4
@@ -17,16 +17,16 @@
1717 * Renato Araujo Oliveira Filho <renato@canonical.com>
1818 */
1919
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
22−import Ubuntu.Components.ListItems 0.1 as ListItem
20+import QtQuick 2.4
21+import Ubuntu.Components 1.3
22+import Ubuntu.Components.ListItems 1.3 as ListItem
2323
2424Rectangle {
2525 color: "black"
2626 id: root
2727
2828 Component.onCompleted: {
29− Theme.name = "Ubuntu.Components.Themes.SuruGradient"
29+ theme.name = "Ubuntu.Components.Themes.SuruGradient"
3030 }
3131
3232 PageStack {
qml/Panel/Indicators/client/IndicatorsList.qml+3−3
@@ -17,9 +17,9 @@
1717 * Renato Araujo Oliveira Filho <renato@canonical.com>
1818 */
1919
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
22−import Ubuntu.Components.ListItems 0.1 as ListItem
20+import QtQuick 2.4
21+import Ubuntu.Components 1.3
22+import Ubuntu.Components.ListItems 1.3 as ListItem
2323import Unity.Indicators 0.1 as Indicators
2424import "../.."
2525
qml/Panel/Indicators/client/IndicatorsTree.qml+2−2
@@ -17,8 +17,8 @@
1717 * Nick Dedekind <nick.dededkind@canonical.com>
1818 */
1919
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
20+import QtQuick 2.4
21+import Ubuntu.Components 1.3
2222import Unity.Indicators 0.1 as Indicators
2323import ".."
2424
qml/Panel/IndicatorsBar.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121Item {
qml/Panel/IndicatorsMenu.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import "../Components"
2121import "Indicators"
qml/Panel/MenuContent.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import Unity.Indicators 0.1 as Indicators
2121import Utils 0.1
2222import "../Components"
qml/Panel/Panel.qml+8−5
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Unity.Application 0.1
2020import "../Components"
2121import "../Components/PanelState"
@@ -28,6 +28,7 @@ Item {
2828 property alias callHint: __callHint
2929 property bool fullscreenMode: false
3030 property real indicatorAreaShowProgress: 1.0
31+ property bool locked: false
3132
3233 opacity: fullscreenMode && indicators.fullyClosed ? 0.0 : 1.0
3334
@@ -48,6 +49,7 @@ Item {
4849 MouseArea {
4950 anchors.fill: parent
5051 onClicked: if (indicators.fullyOpened) indicators.hide();
52+ hoverEnabled: true // should also eat hover events, otherwise they will pass through
5153 }
5254 }
5355
@@ -135,7 +137,7 @@ Item {
135137 }
136138
137139 shown: false
138− width: root.width - (PanelState.buttonsVisible ? windowControlButtons.width : 0)
140+ width: root.width - (windowControlButtons.visible ? windowControlButtons.width : 0)
139141 minimizedPanelHeight: units.gu(3)
140142 expandedPanelHeight: units.gu(7)
141143 openedHeight: root.height - indicatorOrangeLine.height
@@ -163,13 +165,14 @@ Item {
163165
164166 WindowControlButtons {
165167 id: windowControlButtons
168+ objectName: "panelWindowControlButtons"
166169 anchors {
167170 left: parent.left
168171 top: parent.top
169172 margins: units.gu(0.7)
170173 }
171174 height: indicators.minimizedPanelHeight - anchors.margins * 2
172− visible: PanelState.buttonsVisible
175+ visible: PanelState.buttonsVisible && !root.locked
173176 onClose: PanelState.close()
174177 onMinimize: PanelState.minimize()
175178 onMaximize: PanelState.maximize()
@@ -188,7 +191,7 @@ Item {
188191 id: __callHint
189192 anchors {
190193 top: parent.top
191− left: PanelState.buttonsVisible ? windowControlButtons.right : parent.left
194+ left: windowControlButtons.visible ? windowControlButtons.right : parent.left
192195 }
193196 height: indicators.minimizedPanelHeight
194197 visible: active && indicators.state == "initial"
qml/Panel/PanelBackground.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Rectangle {
2020 color: "black"
qml/Panel/PanelSeparatorLine.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Rectangle {
2020 property real saturation: 1.0
qml/Panel/PanelVelocityCalculator.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import Ubuntu.Gestures 0.1
1919
2020Item {
qml/Rotation/HalfLoopRotationAnimation.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818
1919SequentialAnimation {
2020 id: root
qml/Rotation/ImmediateRotationAction.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818
1919ScriptAction {
2020 property var info
qml/Rotation/NinetyRotationAnimation.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818
1919SequentialAnimation {
2020 id: root
qml/Rotation/RotationStates.qml+4−4
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Powerd 0.1
2020
2121// Why the state machine is done that way:
@@ -83,7 +83,7 @@ StateGroup {
8383 }
8484
8585 function tryUpdateState() {
86− if (d.transitioning || (!d.startingUp && !root.shell.orientationChangesEnabled)) {
86+ if (d.transitioning || (!d.startingUp && !root.orientedShell.orientationChangesEnabled)) {
8787 return;
8888 }
8989
@@ -95,7 +95,7 @@ StateGroup {
9595 }
9696
9797 property Connections shellConnections: Connections {
98− target: root.shell
98+ target: root.orientedShell
9999 onOrientationChangesEnabledChanged: {
100100 d.tryUpdateState();
101101 }
qml/ScopeTool.qml+3−3
@@ -14,9 +14,9 @@
1414* along with this program. If not, see <http://www.gnu.org/licenses/>.
1515*/
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import Ubuntu.Components.Popups 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.Popups 1.3
2020import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
2121import Utils 0.1
2222import Unity 0.2
qml/Shell.qml+38−58
@@ -14,13 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import QtQuick.Window 2.0
17+import QtQuick 2.4
18+import QtQuick.Window 2.2
1919import AccountsService 0.1
20−import GSettings 1.0
2120import Unity.Application 0.1
22−import Ubuntu.Components 0.1
23−import Ubuntu.Components.Popups 1.0
21+import Ubuntu.Components 1.3
22+import Ubuntu.Components.Popups 1.3
2423import Ubuntu.Gestures 0.1
2524import Ubuntu.Telephony 0.1 as Telephony
2625import Unity.Connectivity 0.1
@@ -41,6 +40,7 @@ import Unity.Notifications 1.0 as NotificationBackend
4140import Unity.Session 0.1
4241import Unity.DashCommunicator 0.1
4342import Unity.Indicators 0.1 as Indicators
43+import Cursor 1.0
4444
4545
4646Item {
@@ -49,21 +49,21 @@ Item {
4949 // to be set from outside
5050 property int orientationAngle: 0
5151 property int orientation
52− property int primaryOrientation
53− property int nativeOrientation
52+ property Orientations orientations
5453 property real nativeWidth
5554 property real nativeHeight
5655 property alias indicatorAreaShowProgress: panel.indicatorAreaShowProgress
5756 property bool beingResized
5857 property string usageScenario: "phone" // supported values: "phone", "tablet" or "desktop"
5958 property string mode: "full-greeter"
59+ property bool cursorVisible: false
6060 function updateFocusedAppOrientation() {
6161 applicationsDisplayLoader.item.updateFocusedAppOrientation();
6262 }
6363 function updateFocusedAppOrientationAnimated() {
6464 applicationsDisplayLoader.item.updateFocusedAppOrientationAnimated();
6565 }
66− property bool hasMouse
66+ property bool hasMouse: false
6767
6868 // to be read from outside
6969 readonly property int mainAppWindowOrientationAngle:
@@ -85,7 +85,7 @@ Item {
8585 } else if (greeter && greeter.shown) {
8686 return Qt.PrimaryOrientation;
8787 } else if (mainApp) {
88− return mainApp.supportedOrientations;
88+ return shell.orientations.map(mainApp.supportedOrientations);
8989 } else {
9090 // we just don't care
9191 return Qt.PortraitOrientation
@@ -107,9 +107,11 @@ Item {
107107 enabled: greeter && !greeter.waiting
108108
109109 property real edgeSize: units.gu(2)
110− property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
111− property url background: asImageTester.status == Image.Ready ? asImageTester.source
112− : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
110+
111+ WallpaperResolver {
112+ id: wallpaperResolver
113+ width: shell.width
114+ }
113115
114116 readonly property alias greeter: greeterLoader.item
115117
@@ -130,31 +132,6 @@ Item {
130132 shell.activateApplication(app);
131133 }
132134
133− // This is a dummy image to detect if the custom AS set wallpaper loads successfully.
134− Image {
135− id: asImageTester
136− source: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : ""
137− height: 0
138− width: 0
139− sourceSize.height: 0
140− sourceSize.width: 0
141− }
142−
143− GSettings {
144− id: backgroundSettings
145− schema.id: "org.gnome.desktop.background"
146− }
147−
148− // This is a dummy image to detect if the custom GSettings set wallpaper loads successfully.
149− Image {
150− id: gsImageTester
151− source: backgroundSettings.pictureUri && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : ""
152− height: 0
153− width: 0
154− sourceSize.height: 0
155− sourceSize.width: 0
156− }
157−
158135 Binding {
159136 target: LauncherModel
160137 property: "applicationManager"
@@ -162,7 +139,7 @@ Item {
162139 }
163140
164141 Component.onCompleted: {
165− Theme.name = "Ubuntu.Components.Themes.SuruGradient"
142+ theme.name = "Ubuntu.Components.Themes.SuruGradient"
166143 if (ApplicationManager.count > 0) {
167144 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
168145 }
@@ -190,18 +167,13 @@ Item {
190167 onScreenshotTriggered: screenGrabber.capture();
191168 }
192169
193− ScreenGrabber {
194− id: screenGrabber
195− z: dialogs.z + 10
196− }
197−
198170 GlobalShortcut {
199171 // dummy shortcut to force creation of GlobalShortcutRegistry before WindowKeyFilter
200172 }
201173
202174 WindowKeysFilter {
203− Keys.onPressed: physicalKeysMapper.onKeyPressed(event);
204− Keys.onReleased: physicalKeysMapper.onKeyReleased(event);
175+ Keys.onPressed: physicalKeysMapper.onKeyPressed(event, currentEventTimestamp);
176+ Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
205177 }
206178
207179 HomeKeyWatcher {
@@ -326,18 +298,13 @@ Item {
326298 }
327299 Binding {
328300 target: applicationsDisplayLoader.item
329− property: "background"
330− value: shell.background
331− }
332− Binding {
333− target: applicationsDisplayLoader.item
334− property: "shellPrimaryOrientation"
335− value: shell.primaryOrientation
301+ property: "orientations"
302+ value: shell.orientations
336303 }
337304 Binding {
338305 target: applicationsDisplayLoader.item
339− property: "nativeOrientation"
340− value: shell.nativeOrientation
306+ property: "background"
307+ value: wallpaperResolver.background
341308 }
342309 Binding {
343310 target: applicationsDisplayLoader.item
@@ -432,7 +399,7 @@ Item {
432399 tabletMode: shell.usageScenario != "phone"
433400 launcherOffset: launcher.progress
434401 forcedUnlock: tutorial.running
435− background: shell.background
402+ background: wallpaperResolver.background
436403
437404 // avoid overlapping with Launcher's edge drag area
438405 // FIXME: Fix TouchRegistry & friends and remove this workaround
@@ -564,6 +531,7 @@ Item {
564531
565532 fullscreenMode: (topmostApplicationIsFullscreen && !lightDM.greeter.active && launcher.progress == 0)
566533 || greeter.hasLockedApp
534+ locked: greeter && greeter.active
567535 }
568536
569537 Launcher {
@@ -607,7 +575,7 @@ Item {
607575 id: wizard
608576 objectName: "wizard"
609577 anchors.fill: parent
610− background: shell.background
578+ background: wallpaperResolver.background
611579
612580 function unlockWhenDoneWithWizard() {
613581 if (!active) {
@@ -638,6 +606,7 @@ Item {
638606 model: NotificationBackend.Model
639607 margin: units.gu(1)
640608 hasMouse: shell.hasMouse
609+ background: wallpaperResolver.background
641610
642611 y: topmostIsFullscreen ? 0 : panel.panelHeight
643612 height: parent.height - (topmostIsFullscreen ? 0 : panel.panelHeight)
@@ -684,9 +653,21 @@ Item {
684653 onShowHome: showHome()
685654 }
686655
656+ ScreenGrabber {
657+ id: screenGrabber
658+ rotationAngle: -shell.orientationAngle
659+ z: dialogs.z + 10
660+ }
661+
662+ Cursor {
663+ id: cursor
664+ visible: shell.hasMouse
665+ z: screenGrabber.z + 1
666+ }
667+
687668 Rectangle {
688669 id: shutdownFadeOutRectangle
689− z: screenGrabber.z + 10
670+ z: cursor.z + 1
690671 enabled: false
691672 visible: false
692673 color: "black"
@@ -703,5 +684,4 @@ Item {
703684 }
704685 }
705686 }
706−
707687}
qml/Stages/AbstractStage.qmlnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import GSettings 1.0
20+
21+Rectangle {
22+ id: root
23+
24+ color: "#111111"
25+
26+ // Controls to be set from outside
27+ property bool altTabPressed
28+ property url background
29+ property bool beingResized
30+ property int dragAreaWidth
31+ property bool interactive
32+ property real inverseProgress // This is the progress for left edge drags, in pixels.
33+ property bool keepDashRunning: true
34+ property real maximizedAppTopMargin
35+ property real nativeHeight
36+ property real nativeWidth
37+ property QtObject orientations
38+ property int shellOrientation
39+ property int shellOrientationAngle
40+ property bool spreadEnabled: true // If false, animations and right edge will be disabled
41+ property bool suspended
42+
43+ // To be read from outside
44+ property var mainApp: null
45+ property int mainAppWindowOrientationAngle
46+ property bool orientationChangesEnabled
47+
48+ // Shared code for use in stage implementations
49+ GSettings {
50+ id: lifecycleExceptions
51+ schema.id: "com.canonical.qtmir"
52+ }
53+
54+ function isExemptFromLifecycle(appId) {
55+ var shortAppId = appId.split('_')[0];
56+ for (var i = 0; i < lifecycleExceptions.lifecycleExemptAppids.length; i++) {
57+ if (shortAppId === lifecycleExceptions.lifecycleExemptAppids[i]) {
58+ return true;
59+ }
60+ }
61+ return false;
62+ }
63+}
qml/Stages/Animations/BaseSessionAnimation.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919/* This is the base case for surface animations, used when adding/removing * child surfaces.
2020 * The class is meant to be overridden and changes/animations provided for state changes.
qml/Stages/Animations/SwipeFromBottomAnimation.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020BaseSessionAnimation {
2121 id: animation
qml/Stages/ApplicationWindow.qml+4−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Unity.Application 0.1
2020
2121FocusScope {
@@ -27,6 +27,8 @@ FocusScope {
2727 readonly property bool fullscreen: application ? application.fullscreen : false
2828 property alias interactive: sessionContainer.interactive
2929 property bool orientationChangesEnabled: d.supportsSurfaceResize ? d.surfaceOldEnoughToBeResized : true
30+ readonly property string title: sessionContainer.surface && sessionContainer.surface.name !== "" ?
31+ sessionContainer.surface.name : d.name
3032
3133 // to be set from outside
3234 property QtObject application
qml/Stages/DecoratedWindow.qml+9−6
@@ -16,8 +16,8 @@
1616 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
1717 */
1818
19−import QtQuick 2.3
20−import Ubuntu.Components 1.1
19+import QtQuick 2.4
20+import Ubuntu.Components 1.3
2121import Unity.Application 0.1
2222
2323FocusScope {
@@ -31,9 +31,10 @@ FocusScope {
3131 property bool highlightShown: false
3232 property real shadowOpacity: 1
3333
34− signal close();
35− signal maximize();
36− signal minimize();
34+ signal close()
35+ signal maximize()
36+ signal minimize()
37+ signal decorationPressed()
3738
3839 BorderImage {
3940 anchors {
@@ -61,13 +62,15 @@ FocusScope {
6162
6263 WindowDecoration {
6364 id: decoration
65+ target: root.parent
6466 objectName: application ? "appWindowDecoration_" + application.appId : "appWindowDecoration_null"
6567 anchors { left: parent.left; top: parent.top; right: parent.right }
6668 height: units.gu(3)
67− title: model.name
69+ title: window.title !== "" ? window.title : model.name
6870 onClose: root.close();
6971 onMaximize: root.maximize();
7072 onMinimize: root.minimize();
73+ onPressed: root.decorationPressed();
7174 visible: decorationShown
7275 }
7376
qml/Stages/DesktopSpread.qml+1−1
@@ -16,7 +16,7 @@
1616
1717import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.2
19+import Ubuntu.Components 1.3
2020import Ubuntu.Gestures 0.1
2121import Unity.Application 0.1
2222
qml/Stages/DesktopSpreadDelegate.qml+2−2
@@ -16,8 +16,8 @@
1616 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
1717 */
1818
19−import QtQuick 2.3
20−import Ubuntu.Components 1.1
19+import QtQuick 2.4
20+import Ubuntu.Components 1.3
2121import Unity.Application 0.1
2222
2323Item {
qml/Stages/DesktopStage.qml+98−40
@@ -18,43 +18,25 @@
1818
1919import QtQuick 2.4
2020import QtQuick.Layouts 1.1
21−import Ubuntu.Components 1.1
21+import Ubuntu.Components 1.3
2222import Unity.Application 0.1
2323import "../Components"
2424import "../Components/PanelState"
25+import "../Components"
2526import Utils 0.1
2627import Ubuntu.Gestures 0.1
2728
28−Rectangle {
29+AbstractStage {
2930 id: root
3031 anchors.fill: parent
3132
32− // Controls to be set from outside
33− property int dragAreaWidth // just to comply with the interface shared between stages
34− property real maximizedAppTopMargin
35− property bool interactive
36− property bool spreadEnabled // just to comply with the interface shared between stages
37− property real inverseProgress: 0 // just to comply with the interface shared between stages
38− property int shellOrientationAngle: 0
39− property int shellOrientation
40− property int shellPrimaryOrientation
41− property int nativeOrientation
42− property bool beingResized: false
43− property bool keepDashRunning: true
44− property bool suspended: false
45− property alias background: wallpaper.source
46− property alias altTabPressed: spread.altTabPressed
47−
4833 // functions to be called from outside
4934 function updateFocusedAppOrientation() { /* TODO */ }
5035 function updateFocusedAppOrientationAnimated() { /* TODO */}
5136
52− // To be read from outside
53− readonly property var mainApp: ApplicationManager.focusedApplicationId
37+ mainApp: ApplicationManager.focusedApplicationId
5438 ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
5539 : null
56− property int mainAppWindowOrientationAngle: 0
57− readonly property bool orientationChangesEnabled: false
5840
5941 Connections {
6042 target: ApplicationManager
@@ -86,6 +68,22 @@ Rectangle {
8668 var index = indexOf(focusedAppId);
8769 return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null
8870 }
71+ property int foregroundMaximizedAppIdIndex: -1
72+
73+ function updateForegroundMaximizedApp() {
74+ for (var i = 0; i < appRepeater.count; i++) {
75+ var item = appRepeater.itemAt(i);
76+
77+ if (item && item.visuallyMaximized) {
78+ var app = ApplicationManager.get(i);
79+ if (app) {
80+ foregroundMaximizedAppIdIndex = i;
81+ return;
82+ }
83+ }
84+ }
85+ foregroundMaximizedAppIdIndex = -1;
86+ }
8987
9088 function indexOf(appId) {
9189 for (var i = 0; i < ApplicationManager.count; i++) {
@@ -111,6 +109,7 @@ Rectangle {
111109 property: "buttonsVisible"
112110 value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.state === "maximized"
113111 }
112+ Component.onDestruction: PanelState.buttonsVisible = false;
114113
115114 FocusScope {
116115 id: appContainer
@@ -121,6 +120,7 @@ Rectangle {
121120 CrossFadeImage {
122121 id: wallpaper
123122 anchors.fill: parent
123+ source: root.background
124124 sourceSize { height: root.height; width: root.width }
125125 fillMode: Image.PreserveAspectCrop
126126 }
@@ -130,19 +130,24 @@ Rectangle {
130130 model: ApplicationManager
131131 objectName: "appRepeater"
132132
133+ onItemAdded: priv.updateForegroundMaximizedApp()
134+ onItemRemoved: priv.updateForegroundMaximizedApp()
135+
133136 delegate: FocusScope {
134137 id: appDelegate
138+ objectName: "stageDelegate_" + model.appId
135139 z: ApplicationManager.count - index
136140 y: units.gu(3)
137141 width: units.gu(60)
138142 height: units.gu(50)
139143 focus: model.appId === priv.focusedAppId
140144
141− readonly property int minWidth: units.gu(10)
142− readonly property int minHeight: units.gu(10)
143−
144145 property bool maximized: false
145146 property bool minimized: false
147+ property bool animationsEnabled: true
148+
149+ property bool visuallyMaximized: false
150+ property bool visuallyMinimized: false
146151
147152 onFocusChanged: {
148153 if (focus && ApplicationManager.focusedApplicationId !== model.appId) {
@@ -150,6 +155,16 @@ Rectangle {
150155 }
151156 }
152157
158+ onZChanged: priv.updateForegroundMaximizedApp()
159+ onVisuallyMaximizedChanged: priv.updateForegroundMaximizedApp()
160+
161+ visible: !visuallyMinimized &&
162+ !greeter.fullyShown &&
163+ (priv.foregroundMaximizedAppIdIndex === -1 || priv.foregroundMaximizedAppIdIndex >= index) ||
164+ (spread.state == "altTab" && index === spread.highlightedIndex)
165+
166+ onVisibleChanged: console.log("VISIBLE", model.appId, visible)
167+
153168 Binding {
154169 target: ApplicationManager.get(index)
155170 property: "requestedState"
@@ -161,37 +176,78 @@ Rectangle {
161176 value: ApplicationInfoInterface.RequestedRunning // Always running for now
162177 }
163178
164− function maximize() {
179+ function maximize(animated) {
180+ animationsEnabled = (animated === undefined) || animated;
165181 minimized = false;
166182 maximized = true;
167183 }
168− function minimize() {
184+ function minimize(animated) {
185+ animationsEnabled = (animated === undefined) || animated;
169186 maximized = false;
170187 minimized = true;
171188 }
172− function unmaximize() {
189+ function unmaximize(animated) {
190+ animationsEnabled = (animated === undefined) || animated;
173191 minimized = false;
174192 maximized = false;
175193 }
176194
177195 states: [
178196 State {
179− name: "normal"; when: !appDelegate.maximized && !appDelegate.minimized
197+ name: "normal";
198+ when: !appDelegate.maximized && !appDelegate.minimized
199+ PropertyChanges {
200+ target: appDelegate;
201+ visuallyMinimized: false;
202+ visuallyMaximized: false
203+ }
180204 },
181205 State {
182206 name: "maximized"; when: appDelegate.maximized
183− PropertyChanges { target: appDelegate; x: 0; y: 0; width: root.width; height: root.height }
207+ PropertyChanges {
208+ target: appDelegate;
209+ x: 0; y: 0;
210+ width: root.width; height: root.height;
211+ visuallyMinimized: false;
212+ visuallyMaximized: true
213+ }
184214 },
185215 State {
186216 name: "minimized"; when: appDelegate.minimized
187− PropertyChanges { target: appDelegate; x: -appDelegate.width / 2; scale: units.gu(5) / appDelegate.width; opacity: 0 }
217+ PropertyChanges {
218+ target: appDelegate;
219+ x: -appDelegate.width / 2;
220+ scale: units.gu(5) / appDelegate.width;
221+ opacity: 0
222+ visuallyMinimized: true;
223+ visuallyMaximized: false
224+ }
188225 }
189226 ]
190227 transitions: [
191228 Transition {
192− from: "maximized,minimized,normal,"
193− to: "maximized,minimized,normal,"
194− PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale" }
229+ to: "normal"
230+ enabled: appDelegate.animationsEnabled
231+ PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
232+ PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale,opacity" }
233+ },
234+ Transition {
235+ to: "maximized"
236+ enabled: appDelegate.animationsEnabled
237+ PropertyAction { target: appDelegate; property: "visuallyMinimized" }
238+ SequentialAnimation {
239+ PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale,opacity" }
240+ PropertyAction { target: appDelegate; property: "visuallyMaximized" }
241+ }
242+ },
243+ Transition {
244+ to: "minimized"
245+ enabled: appDelegate.animationsEnabled
246+ PropertyAction { target: appDelegate; property: "visuallyMaximized" }
247+ SequentialAnimation {
248+ PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale,opacity" }
249+ PropertyAction { target: appDelegate; property: "visuallyMinimized" }
250+ }
195251 },
196252 Transition {
197253 from: ""
@@ -215,12 +271,12 @@ Rectangle {
215271 when: index == spread.highlightedIndex && blurLayer.ready
216272 }
217273
218− WindowMoveResizeArea {
219− id: windowMoveResizeArea
274+ WindowResizeArea {
275+ objectName: "windowResizeArea"
220276 target: appDelegate
221− minWidth: appDelegate.minWidth
222− minHeight: appDelegate.minHeight
223− resizeHandleWidth: units.gu(2)
277+ minWidth: units.gu(10)
278+ minHeight: units.gu(10)
279+ borderThickness: units.gu(2)
224280 windowId: model.appId // FIXME: Change this to point to windowId once we have such a thing
225281
226282 onPressed: { ApplicationManager.focusApplication(model.appId) }
@@ -238,8 +294,9 @@ Rectangle {
238294 focus: true
239295
240296 onClose: ApplicationManager.stopApplication(model.appId)
241− onMaximize: appDelegate.maximize()
297+ onMaximize: appDelegate.maximized ? appDelegate.unmaximize() : appDelegate.maximize()
242298 onMinimize: appDelegate.minimize()
299+ onDecorationPressed: { ApplicationManager.focusApplication(model.appId) }
243300 }
244301 }
245302 }
@@ -272,5 +329,6 @@ Rectangle {
272329 anchors.fill: parent
273330 workspace: appContainer
274331 focus: state == "altTab"
332+ altTabPressed: root.altTabPressed
275333 }
276334}
qml/Stages/MainViewStyle.qml+35−27
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2012 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -13,51 +13,60 @@
1313 * You should have received a copy of the GNU Lesser General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
16−import QtQuick 2.0
17−import Ubuntu.Components 1.1
16+import QtQuick 2.4
17+import Ubuntu.Components 1.3
1818
1919// FIXME: copied with slight modifications from Ubuntu UI Toolkit's Ambiance's theme
2020Item {
21− // styling properties
2221 anchors.fill: parent
2322 z: -1
2423 id: mainViewStyle
2524
25+ property var theme
26+
27+ /*!
28+ Color of the header's background.
29+
30+ \sa backgroundColor, footerColor
31+ */
32+ property color headerColor: styledItem.headerColor
33+
2634 /*!
27− The background texture of the main view. The image will be drawn over the background color,
28− so if it has (semi-)transparent pixels, in those pixels the background color will be visible.
29− */
30− property url backgroundSource: "graphics/background_paper.png"
31− property var theme
35+ Color of the background.
36+
37+ The background is usually a single color. However if \l headerColor
38+ or \l footerColor are set then a gradient of colors will be drawn.
39+
40+ \sa footerColor, headerColor
41+ */
42+ property color backgroundColor: styledItem.backgroundColor
43+
44+ /*!
45+ Color of the footer's background.
46+
47+ \sa backgroundColor, headerColor
48+ */
49+ property color footerColor: styledItem.footerColor
3250
3351 Gradient {
3452 id: backgroundGradient
35− GradientStop { position: 0.0; color: styledItem.headerColor }
36− GradientStop { position: 0.83; color: styledItem.backgroundColor }
37− GradientStop { position: 1.0; color: styledItem.footerColor }
53+ GradientStop { position: 0.0; color: mainViewStyle.headerColor }
54+ GradientStop { position: 0.83; color: mainViewStyle.backgroundColor }
55+ GradientStop { position: 1.0; color: mainViewStyle.footerColor }
3856 }
3957
4058 Rectangle {
4159 id: backgroundColor
4260 anchors.fill: parent
43− color: styledItem.backgroundColor
61+ color: mainViewStyle.backgroundColor
4462 gradient: internals.isGradient ? backgroundGradient : null
4563 }
4664
47− Image {
48− id: backgroundTexture
49− anchors.fill: parent
50− source: mainViewStyle.theme.name === "Ambiance" ? mainViewStyle.backgroundSource : ""
51− fillMode: Image.Tile
52− asynchronous: true
53− cache: false
54− visible: status === Image.Ready
55− }
56−
5765 QtObject {
5866 id: internals
59− property bool isGradient: styledItem.backgroundColor != styledItem.headerColor ||
60− styledItem.backgroundColor != styledItem.footerColor
67+ property bool isGradient: mainViewStyle.backgroundColor != mainViewStyle.headerColor ||
68+ mainViewStyle.backgroundColor != mainViewStyle.footerColor
69+
6170 /*
6271 As we don't know the order the property bindings and onXXXChanged signals are evaluated
6372 we should rely only on one property when changing the theme to avoid intermediate
@@ -65,8 +74,7 @@ Item {
6574
6675 Qt bug: https://bugreports.qt-project.org/browse/QTBUG-11712
6776 */
68− property string theme: (ColorUtils.luminance(styledItem.backgroundColor) >= 0.85) ? "Ambiance" :
69− (isGradient ? "SuruGradient" : "SuruDark")
77+ property string theme: (ColorUtils.luminance(styledItem.backgroundColor) >= 0.85) ? "Ambiance" : "SuruDark"
7078 }
7179
7280 // automatically select the appropriate theme depending on the background colors
qml/Stages/OrientationChangeAnimation.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818
1919QtObject {
2020 id: root
qml/Stages/PageHeadStyle.qmldeleted−76
@@ -1,76 +0,0 @@
1−/*
2− * Copyright 2014 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU Lesser General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU Lesser General Public License for more details.
12− *
13− * You should have received a copy of the GNU Lesser General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−import QtQuick 2.2
17−import Ubuntu.Components 1.1
18−import Ubuntu.Components.Styles 1.1 as Style
19−
20−// FIXME: copied with large modifications from Ubuntu UI Toolkit's Ambiance's theme
21−Style.PageHeadStyle {
22− id: headerStyle
23−
24− contentHeight: units.gu(7)
25− separatorSource: "graphics/PageHeaderBaseDividerLight.sci"
26− separatorBottomSource: "graphics/PageHeaderBaseDividerBottom.png"
27− fontWeight: Font.Light
28− fontSize: "x-large"
29− textColor: styledItem.config.foregroundColor
30− textLeftMargin: units.gu(2)
31−
32− implicitHeight: headerStyle.contentHeight
33−
34− property var theme
35−
36− Label {
37− anchors {
38− left: parent.left
39− leftMargin: headerStyle.textLeftMargin
40− right: parent.right
41− verticalCenter: parent.verticalCenter
42− }
43− LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft
44− text: styledItem.title
45− font.weight: headerStyle.fontWeight
46− fontSize: headerStyle.fontSize
47− color: headerStyle.textColor
48− elide: Text.ElideRight
49− }
50−
51− BorderImage {
52− id: separator
53− anchors {
54− top: parent.bottom
55− topMargin: separatorBottom.height
56− left: parent.left
57− right: parent.right
58− }
59− source: headerStyle.separatorSource
60− height: styledItem.config.sections.model !== undefined ? units.gu(3) : units.gu(2)
61− asynchronous: true
62− cache: true
63− }
64−
65− Image {
66− id: separatorBottom
67− anchors {
68− top: separator.bottom
69− left: parent.left
70− right: parent.right
71− }
72− source: headerStyle.separatorBottomSource
73− asynchronous: true
74− cache: true
75− }
76−}
qml/Stages/PhoneStage.qml+38−40
@@ -14,37 +14,24 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import Unity.Application 0.1
2121import Unity.Session 0.1
2222import Utils 0.1
23+import Powerd 0.1
2324import "../Components"
2425
25−Rectangle {
26+AbstractStage {
2627 id: root
2728
28− // Controls to be set from outside
29− property int dragAreaWidth
30− property real maximizedAppTopMargin
31− property bool interactive
32− property bool spreadEnabled: true // If false, animations and right edge will be disabled
33− property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
3429 property QtObject applicationManager: ApplicationManager
3530 property bool focusFirstApp: true // If false, focused app will appear on right edge like other apps
3631 property bool altTabEnabled: true
3732 property real startScale: 1.1
3833 property real endScale: 0.7
39− property bool keepDashRunning: true
40− property bool suspended: false
41− property int shellOrientationAngle: 0
42− property int shellOrientation
43− property int shellPrimaryOrientation
44− property int nativeOrientation
45− property real nativeWidth
46− property real nativeHeight
47− property bool beingResized: false
34+
4835 onBeingResizedChanged: {
4936 if (beingResized) {
5037 // Brace yourselves for impact!
@@ -56,6 +43,8 @@ Rectangle {
5643 priv.reset();
5744 }
5845 }
46+
47+ // Functions to be called from outside
5948 function updateFocusedAppOrientation() {
6049 if (spreadRepeater.count > 0) {
6150 spreadRepeater.itemAt(0).matchShellOrientation();
@@ -71,7 +60,7 @@ Rectangle {
7160
7261 var supportedOrientations = spreadDelegate.application.supportedOrientations;
7362 if (supportedOrientations === Qt.PrimaryOrientation) {
74− supportedOrientations = spreadDelegate.shellPrimaryOrientation;
63+ supportedOrientations = root.orientations.primary;
7564 }
7665
7766 if (delta === 180 && (supportedOrientations & spreadDelegate.shellOrientation)) {
@@ -85,16 +74,14 @@ Rectangle {
8574 }
8675 }
8776
88− // To be read from outside
89− readonly property var mainApp: applicationManager.focusedApplicationId
77+ mainApp: applicationManager.focusedApplicationId
9078 ? applicationManager.findApplication(applicationManager.focusedApplicationId)
9179 : null
9280
93− property int mainAppWindowOrientationAngle: 0
94− readonly property bool orientationChangesEnabled: priv.focusedAppOrientationChangesEnabled
95− && !priv.focusedAppDelegateIsDislocated
96− && !(priv.focusedAppDelegate && priv.focusedAppDelegate.xBehavior.running)
97− && spreadView.phase === 0
81+ orientationChangesEnabled: priv.focusedAppOrientationChangesEnabled
82+ && !priv.focusedAppDelegateIsDislocated
83+ && !(priv.focusedAppDelegate && priv.focusedAppDelegate.xBehavior.running)
84+ && spreadView.phase === 0
9885
9986 // How far left the stage has been dragged
10087 readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
@@ -106,8 +93,6 @@ Rectangle {
10693
10794 signal opened()
10895
109− color: "#111111"
110−
11196 function select(appId) {
11297 spreadView.snapTo(priv.indexOf(appId));
11398 }
@@ -198,7 +183,8 @@ Rectangle {
198183 }
199184 }
200185
201− property bool focusedAppDelegateIsDislocated: focusedAppDelegate && focusedAppDelegate.x !== 0
186+ property bool focusedAppDelegateIsDislocated: focusedAppDelegate &&
187+ (focusedAppDelegate.x !== 0 || focusedAppDelegate.xBehavior.running)
202188
203189 function indexOf(appId) {
204190 for (var i = 0; i < root.applicationManager.count; i++) {
@@ -438,16 +424,21 @@ Rectangle {
438424 dropShadow: spreadView.active || priv.focusedAppDelegateIsDislocated
439425 focusFirstApp: root.focusFirstApp
440426
427+ readonly property bool isDash: model.appId == "unity8-dash"
428+
429+ readonly property bool canSuspend: model.isTouchApp
430+ && !isExemptFromLifecycle(model.appId)
431+
441432 Binding {
442433 target: appDelegate.application
443434 property: "requestedState"
444− value: (isDash && root.keepDashRunning) || (!root.suspended && appDelegate.focus)
445− ? ApplicationInfoInterface.RequestedRunning
446− : ApplicationInfoInterface.RequestedSuspended
435+ value: !canSuspend
436+ || (isDash && root.keepDashRunning)
437+ || (!root.suspended && appDelegate.focus)
438+ ? ApplicationInfoInterface.RequestedRunning
439+ : ApplicationInfoInterface.RequestedSuspended
447440 }
448441
449− readonly property bool isDash: model.appId == "unity8-dash"
450−
451442 z: isDash && !spreadView.active ? -1 : behavioredIndex
452443
453444 x: {
@@ -484,7 +475,6 @@ Rectangle {
484475
485476 property var xBehavior: xBehavior
486477 Behavior on x {
487− id: xBehavior
488478 enabled: root.spreadEnabled &&
489479 !spreadView.active &&
490480 !snapAnimation.running &&
@@ -492,6 +482,7 @@ Rectangle {
492482 priv.animateX &&
493483 !root.beingResized
494484 UbuntuNumberAnimation {
485+ id: xBehavior
495486 duration: UbuntuAnimation.BriskDuration
496487 }
497488 }
@@ -531,15 +522,22 @@ Rectangle {
531522 return progress;
532523 }
533524
534− // Hiding tiles when their progress is negative or reached the maximum
535− visible: (progress >= 0 && progress < 1.7)
536− || (isDash && priv.focusedAppDelegateIsDislocated)
525+ // Hide tile when progress is such that it will be off screen.
526+ property bool occluded: {
527+ if (spreadView.active && (progress >= 0 && progress < 1.7)) return false;
528+ else if (!spreadView.active && isFocused) return false;
529+ else if (xBehavior.running) return false;
530+ else if (z <= 1 && priv.focusedAppDelegateIsDislocated) return false;
531+ return true;
532+ }
537533
534+ visible: Powerd.status == Powerd.On &&
535+ !greeter.fullyShown &&
536+ !occluded
538537
539538 shellOrientationAngle: root.shellOrientationAngle
540539 shellOrientation: root.shellOrientation
541− shellPrimaryOrientation: root.shellPrimaryOrientation
542− nativeOrientation: root.nativeOrientation
540+ orientations: root.orientations
543541
544542 onClicked: {
545543 if (root.altTabEnabled && spreadView.phase == 2) {
qml/Stages/SessionContainer.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515*/
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "Animations"
1919
2020FocusScope {
qml/Stages/ShimStage.qml+3−3
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
20−Rectangle {
20+AbstractStage {
2121 id: shimStage
2222
2323 anchors.fill: parent
qml/Stages/Splash.qml+25−30
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515*/
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.Themes 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.Themes 1.3
2020import "../Components"
2121
22−import Ubuntu.Components.Themes.Ambiance 1.1 as Ambiance
22+import Ubuntu.Components.Themes.Ambiance 1.3 as Ambiance
2323
2424Item {
2525 id: root
@@ -29,7 +29,7 @@ Item {
2929 property color footerColor: d.undefinedColor
3030 property alias imageSource: overlaidImage.source
3131 property url icon
32− property alias title: header.title
32+ property alias title: headerConfig.title
3333 property alias showHeader: header.visible
3434
3535 Ambiance.Palette {
@@ -62,40 +62,36 @@ Item {
6262 : root.footerColor
6363
6464 // FIXME: fake a Theme object as to expose the Palette corresponding to the backgroundColor (see MainViewStyle.qml)
65− property var theme: QtObject {
65+ readonly property var fakeTheme: QtObject {
6666 property string name
67− property Palette palette: Qt.createQmlObject("import QtQuick 2.2;\
68− import Ubuntu.Components.Themes.%1 1.1;\
69− Palette {}".arg(styledItem.theme.name),
67+ property Palette palette: Qt.createQmlObject("import QtQuick 2.4;\
68+ import Ubuntu.Components.Themes.%1 1.3;\
69+ Palette {}".arg(styledItem.fakeTheme.name),
7070 styledItem, "dynamicPalette");
7171 }
7272
7373 // FIXME: should instead use future toolkit API:
7474 // style: theme.createStyleComponent("MainViewStyle.qml", styledItem)
75− style: Component { MainViewStyle {theme: styledItem.theme} }
75+ style: Component { MainViewStyle {theme: styledItem.fakeTheme} }
7676 }
7777
78− StyledItem {
78+ Ambiance.PageHeadStyle {
7979 id: header
8080 anchors {
81− left: parent.left
81+ left: parent.left;
8282 right: parent.right
8383 }
84− visible: false
85−
86− // mimic API of toolkit's AppHeader component required by PageHeadStyle
87− property Item pageStack
88− property Item contents
89− property string title
90− property var tabsModel
91− property var config: QtObject {
92− property color foregroundColor: styledItem.theme.palette.selected.backgroundText
93− property var sections: QtObject {}
84+ property var styledItem: header
85+ // FIXME Keep in sync with SDK's MainView.qml values of these two colors
86+ property color dividerColor: Qt.darker(styledItem.backgroundColor, 1.1)
87+ property color panelColor: Qt.lighter(styledItem.backgroundColor, 1.1)
88+ panelForegroundColor: config.foregroundColor
89+ config: PageHeadConfiguration {
90+ id: headerConfig
91+ foregroundColor: styledItem.fakeTheme.palette.selected.backgroundText
9492 }
9593
96− // FIXME: should instead use future toolkit API:
97− // style: theme.createStyleComponent("PageHeadStyle.qml", header)
98− style: Component { PageHeadStyle {theme: styledItem.theme} }
94+ property var contents: null
9995 }
10096
10197 Image {
@@ -121,14 +117,13 @@ Item {
121117 visible: d.showIcon
122118
123119 radius: "medium"
124− borderSource: "none"
125−
126− image: Image {
120+ aspect: UbuntuShape.Flat
121+ sourceFillMode: Image.PreserveAspectCrop
122+ source: Image {
127123 id: iconImage
128124 sourceSize.width: iconShape.width
129125 sourceSize.height: iconShape.height
130126 source: d.showIcon ? root.icon : ""
131− fillMode: Image.PreserveAspectCrop
132127 }
133128 }
134129
@@ -139,7 +134,7 @@ Item {
139134 anchors.topMargin: units.gu(2)
140135 fontSize: "large"
141136
142− color: styledItem.theme.palette.selected.backgroundText
137+ color: styledItem.fakeTheme.palette.selected.backgroundText
143138 visible: d.showIcon
144139 }
145140
qml/Stages/SpreadDelegate.qml+11−12
@@ -17,9 +17,9 @@
1717 * Daniel d'Andrada <daniel.dandrada@canonical.com>
1818 */
1919
20−import QtQuick 2.0
21−import QtQuick.Window 2.0
22−import Ubuntu.Components 1.1
20+import QtQuick 2.4
21+import QtQuick.Window 2.2
22+import Ubuntu.Components 1.3
2323import "../Components"
2424
2525FocusScope {
@@ -42,8 +42,7 @@ FocusScope {
4242 property alias application: appWindow.application
4343 property int shellOrientationAngle
4444 property int shellOrientation
45− property int shellPrimaryOrientation
46− property int nativeOrientation
45+ property QtObject orientations
4746
4847 function matchShellOrientation() {
4948 if (!root.application)
@@ -157,7 +156,7 @@ FocusScope {
157156 var supportedOrientations = root.application.supportedOrientations;
158157
159158 if (supportedOrientations === Qt.PrimaryOrientation) {
160− supportedOrientations = root.shellPrimaryOrientation;
159+ supportedOrientations = root.orientations.primary;
161160 }
162161
163162 // If it doesn't support shell's current orientation
@@ -166,18 +165,18 @@ FocusScope {
166165 if (supportedOrientations & root.shellOrientation) {
167166 chosenOrientation = root.shellOrientation;
168167 } else if (supportedOrientations & Qt.PortraitOrientation) {
169− chosenOrientation = Qt.PortraitOrientation;
168+ chosenOrientation = root.orientations.portrait;
170169 } else if (supportedOrientations & Qt.LandscapeOrientation) {
171− chosenOrientation = Qt.LandscapeOrientation;
170+ chosenOrientation = root.orientations.landscape;
172171 } else if (supportedOrientations & Qt.InvertedPortraitOrientation) {
173− chosenOrientation = Qt.InvertedPortraitOrientation;
172+ chosenOrientation = root.orientations.invertedPortrait;
174173 } else if (supportedOrientations & Qt.InvertedLandscapeOrientation) {
175− chosenOrientation = Qt.InvertedLandscapeOrientation;
174+ chosenOrientation = root.orientations.invertedLandscape;
176175 } else {
177− chosenOrientation = root.shellPrimaryOrientation;
176+ chosenOrientation = root.orientations.primary;
178177 }
179178
180− return Screen.angleBetween(root.nativeOrientation, chosenOrientation);
179+ return Screen.angleBetween(root.orientations.native_, chosenOrientation);
181180 }
182181
183182 rotation: normalizeAngle(appWindowWithShadow.orientationAngle - root.shellOrientationAngle)
qml/Stages/SpreadMaths.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Utils 0.1
2020
2121Item {
qml/Stages/SurfaceContainer.qml+3−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515*/
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1 // For TouchGate
2020import Utils 0.1 // for InputWatcher
2121import Unity.Application 0.1 // for MirSurfaceItem
@@ -28,6 +28,7 @@ FocusScope {
2828 property bool hadSurface: false
2929 property bool interactive
3030 property int surfaceOrientationAngle: 0
31+ property string name: surface ? surface.name : ""
3132 property bool resizeSurface: true
3233
3334 onSurfaceChanged: {
qml/Stages/TabletStage.qml+43−39
@@ -1,4 +1,4 @@
1−/*
1+/*
22 * Copyright (C) 2014-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
@@ -14,36 +14,20 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import Unity.Application 0.1
2121import Utils 0.1
22+import Powerd 0.1
2223import "../Components"
2324
24−Rectangle {
25+AbstractStage {
2526 id: root
2627 objectName: "stages"
2728 anchors.fill: parent
28− color: "#111111"
29−
30− // Controls to be set from outside
31− property int dragAreaWidth
32− property real maximizedAppTopMargin
33− property bool interactive
34− property alias beingResized: spreadView.beingResized
35−
36− property bool spreadEnabled: true // If false, animations and right edge will be disabled
37−
38− property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
39− property bool keepDashRunning: true
40− property bool suspended: false
41− property int shellOrientationAngle: 0
42− property int shellOrientation
43− property int shellPrimaryOrientation
44− property int nativeOrientation
45− property real nativeWidth
46− property real nativeHeight
29+
30+ // Functions to be called from outside
4731 function updateFocusedAppOrientation() {
4832 var mainStageAppIndex = priv.indexOf(priv.mainStageAppId);
4933 if (mainStageAppIndex >= 0 && mainStageAppIndex < spreadRepeater.count) {
@@ -64,7 +48,7 @@ Rectangle {
6448
6549 var supportedOrientations = spreadDelegate.application.supportedOrientations;
6650 if (supportedOrientations === Qt.PrimaryOrientation) {
67− supportedOrientations = spreadDelegate.shellPrimaryOrientation;
51+ supportedOrientations = spreadDelegate.orientations.primary;
6852 }
6953
7054 if (delta === 180 && (supportedOrientations & spreadDelegate.shellOrientation)) {
@@ -86,10 +70,7 @@ Rectangle {
8670 }
8771 }
8872
89− // To be read from outside
90− property var mainApp: null
91− property int mainAppWindowOrientationAngle: 0
92− readonly property bool orientationChangesEnabled: priv.mainAppOrientationChangesEnabled
73+ orientationChangesEnabled: priv.mainAppOrientationChangesEnabled
9374
9475 onWidthChanged: {
9576 spreadView.selectedIndex = -1;
@@ -130,7 +111,7 @@ Rectangle {
130111 property string oldFocusedAppId: ""
131112 property bool mainAppOrientationChangesEnabled: false
132113
133− property real landscapeHeight: root.nativeOrientation == Qt.LandscapeOrientation ?
114+ property real landscapeHeight: root.orientations.native_ == Qt.LandscapeOrientation ?
134115 root.nativeHeight : root.nativeWidth
135116
136117 property bool shellIsLandscape: root.shellOrientation === Qt.LandscapeOrientation
@@ -166,6 +147,8 @@ Rectangle {
166147 }
167148 }
168149
150+ property bool focusedAppDelegateIsDislocated: focusedAppDelegate &&
151+ (focusedAppDelegate.dragOffset !== 0 || focusedAppDelegate.xTranslateAnimating)
169152 function indexOf(appId) {
170153 for (var i = 0; i < ApplicationManager.count; i++) {
171154 if (ApplicationManager.get(i).appId == appId) {
@@ -302,7 +285,7 @@ Rectangle {
302285 }
303286
304287 property bool animateX: true
305− property bool beingResized: false
288+ property bool beingResized: root.beingResized
306289 onBeingResizedChanged: {
307290 if (beingResized) {
308291 // Brace yourselves for impact!
@@ -629,15 +612,18 @@ Rectangle {
629612
630613 readonly property bool isDash: model.appId == "unity8-dash"
631614
615+ readonly property bool canSuspend: model.isTouchApp
616+ && !isExemptFromLifecycle(model.appId)
617+
632618 Binding {
633619 target: spreadTile.application
634620 property: "requestedState"
635− value: (spreadTile.isDash && root.keepDashRunning)
636− ||
637− (!root.suspended && (model.appId == priv.mainStageAppId
638− || model.appId == priv.sideStageAppId))
639− ? ApplicationInfoInterface.RequestedRunning
640− : ApplicationInfoInterface.RequestedSuspended
621+ value: !canSuspend
622+ || (isDash && root.keepDashRunning)
623+ || (!root.suspended && (model.appId == priv.mainStageAppId
624+ || model.appId == priv.sideStageAppId))
625+ ? ApplicationInfoInterface.RequestedRunning
626+ : ApplicationInfoInterface.RequestedSuspended
641627 }
642628
643629 // FIXME: A regular binding doesn't update any more after closing an app.
@@ -676,6 +662,19 @@ Rectangle {
676662 return tileProgress;
677663 }
678664
665+ // TODO: Hiding tile when progress is such that it will be off screen.
666+ property bool occluded: {
667+ if (spreadView.active) return false;
668+ else if (spreadTile.active) return false;
669+ else if (xTranslateAnimating) return false;
670+ else if (z <= 1 && priv.focusedAppDelegateIsDislocated) return false;
671+ return true;
672+ }
673+
674+ visible: Powerd.status == Powerd.On &&
675+ !greeter.fullyShown &&
676+ !occluded
677+
679678 animatedProgress: {
680679 if (spreadView.phase == 0 && (spreadTile.active || spreadView.nextInStack == index)) {
681680 if (progress < spreadView.positionMarker1) {
@@ -691,9 +690,14 @@ Rectangle {
691690
692691 shellOrientationAngle: wantsMainStage ? root.shellOrientationAngle : 0
693692 shellOrientation: wantsMainStage ? root.shellOrientation : Qt.PortraitOrientation
694− shellPrimaryOrientation: wantsMainStage ? root.shellPrimaryOrientation : Qt.PortraitOrientation
695− nativeOrientation: wantsMainStage ? root.nativeOrientation : Qt.PortraitOrientation
696−
693+ orientations: Orientations {
694+ primary: spreadTile.wantsMainStage ? root.orientations.primary : Qt.PortraitOrientation
695+ native_: spreadTile.wantsMainStage ? root.orientations.native_ : Qt.PortraitOrientation
696+ portrait: root.orientations.portrait
697+ invertedPortrait: root.orientations.invertedPortrait
698+ landscape: root.orientations.landscape
699+ invertedLandscape: root.orientations.invertedLandscape
700+ }
697701
698702 onClicked: {
699703 if (spreadView.phase == 2) {
qml/Stages/TransformedSpreadDelegate.qml+2−2
@@ -16,9 +16,9 @@
1616 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
1717*/
1818
19−import QtQuick 2.0
19+import QtQuick 2.4
2020import Utils 0.1
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222
2323SpreadDelegate {
2424 id: root
qml/Stages/TransformedTabletSpreadDelegate.qml+4−2
@@ -16,9 +16,9 @@
1616 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
1717*/
1818
19−import QtQuick 2.0
19+import QtQuick 2.4
2020import Utils 0.1
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Application 0.1
2323
2424SpreadDelegate {
@@ -48,6 +48,7 @@ SpreadDelegate {
4848 property bool isInSideStage: false
4949
5050 property int dragOffset: 0
51+ readonly property alias xTranslateAnimating: xTranslateAnimation.running
5152
5253 dropShadow: spreadView.active ||
5354 (active
@@ -144,6 +145,7 @@ SpreadDelegate {
144145 spreadView.animateX &&
145146 !spreadView.beingResized
146147 UbuntuNumberAnimation {
148+ id: xTranslateAnimation
147149 duration: UbuntuAnimation.FastDuration
148150 }
149151 }
qml/Stages/WindowDecoration.qml+34−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,25 +12,53 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors: Michael Zanetti <michael.zanetti@canonical.com>
1715 */
1816
19−import QtQuick 2.3
20−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Unity.Application 0.1 // For Mir singleton
19+import Ubuntu.Components 1.3
2120import "../Components"
2221
23−Item {
22+MouseArea {
2423 id: root
2524 clip: true
2625
26+ property Item target
2727 property alias title: titleLabel.text
2828 property bool active: false
29+ hoverEnabled: true
2930
3031 signal close()
3132 signal minimize()
3233 signal maximize()
3334
35+ QtObject {
36+ id: priv
37+ property real distanceX
38+ property real distanceY
39+ property bool dragging
40+ }
41+
42+ onPressedChanged: {
43+ if (pressed) {
44+ var pos = mapToItem(root.target, mouseX, mouseY);
45+ priv.distanceX = pos.x;
46+ priv.distanceY = pos.y;
47+ priv.dragging = true;
48+ Mir.cursorName = "grabbing";
49+ } else {
50+ priv.dragging = false;
51+ Mir.cursorName = "";
52+ }
53+ }
54+ onPositionChanged: {
55+ if (priv.dragging) {
56+ var pos = mapToItem(root.target.parent, mouseX, mouseY);
57+ root.target.x = pos.x - priv.distanceX;
58+ root.target.y = pos.y - priv.distanceY;
59+ }
60+ }
61+
3462 Rectangle {
3563 anchors.fill: parent
3664 anchors.bottomMargin: -radius
qml/Stages/WindowMoveResizeArea.qmldeleted−109
@@ -1,109 +0,0 @@
1−/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors: Michael Zanetti <michael.zanetti@canonical.com>
17− */
18−
19−import QtQuick 2.3
20−import Ubuntu.Components 1.1
21−import Utils 0.1
22−
23−MouseArea {
24− id: root
25− anchors.fill: target
26− anchors.margins: -resizeHandleWidth
27−
28− property var windowStateStorage: WindowStateStorage
29−
30− // The target item managed by this. Must be a parent or a sibling
31− // The area will anchor to it and manage move and resize events
32− property Item target: null
33− property string windowId: ""
34− property int resizeHandleWidth: 0
35− property int minWidth: 0
36− property int minHeight: 0
37−
38− QtObject {
39− id: priv
40− readonly property int windowWidth: root.width - root.resizeHandleWidth * 2
41− readonly property int windowHeight: root.height - resizeHandleWidth * 2
42−
43− property var startPoint
44−
45− property bool resizeTop: false
46− property bool resizeBottom: false
47− property bool resizeLeft: false
48− property bool resizeRight: false
49−
50− }
51−
52− Component.onCompleted: {
53− var windowState = windowStateStorage.getGeometry(root.windowId, Qt.rect(target.x, target.y, target.width, target.height))
54− if (windowState !== undefined) {
55− target.x = windowState.x
56− target.y = windowState.y
57− target.width = windowState.width
58− target.height = windowState.height
59− }
60− }
61−
62− onPressed: {
63− priv.startPoint = Qt.point(mouse.x, mouse.y);
64− priv.resizeTop = mouseY < root.resizeHandleWidth;
65− priv.resizeBottom = mouseY > (root.height - root.resizeHandleWidth);
66− priv.resizeLeft = mouseX < root.resizeHandleWidth;
67− priv.resizeRight = mouseX > (root.width - root.resizeHandleWidth);
68− }
69−
70− onPositionChanged: {
71− var currentPoint = Qt.point(mouse.x, mouse.y);
72− var mouseDiff = Qt.point(currentPoint.x - priv.startPoint.x, currentPoint.y - priv.startPoint.y);
73− var moveDiff = Qt.point(0, 0);
74− var sizeDiff = Qt.point(0, 0);
75− var maxSizeDiff = Qt.point(root.minWidth - root.target.width, root.minHeight - root.target.height)
76−
77− if (priv.resizeTop || priv.resizeBottom || priv.resizeLeft || priv.resizeRight) {
78− if (priv.resizeTop) {
79− sizeDiff.y = Math.max(maxSizeDiff.y, -currentPoint.y + priv.startPoint.y)
80− moveDiff.y = -sizeDiff.y
81− }
82− if (priv.resizeBottom) {
83− sizeDiff.y = Math.max(maxSizeDiff.y, currentPoint.y - priv.startPoint.y)
84− priv.startPoint.y += sizeDiff.y
85− }
86− if (priv.resizeLeft) {
87− sizeDiff.x = Math.max(maxSizeDiff.x, -currentPoint.x + priv.startPoint.x)
88− moveDiff.x = -sizeDiff.x
89− }
90− if (priv.resizeRight) {
91− sizeDiff.x = Math.max(maxSizeDiff.x, currentPoint.x - priv.startPoint.x)
92− priv.startPoint.x += sizeDiff.x
93− }
94−
95− target.x += moveDiff.x;
96− target.y += moveDiff.y;
97− target.width += sizeDiff.x;
98− target.height += sizeDiff.y;
99− } else {
100− target.x += mouseDiff.x;
101− target.y += mouseDiff.y;
102− }
103−
104− }
105−
106− Component.onDestruction: {
107− windowStateStorage.saveGeometry(root.windowId, Qt.rect(target.x, target.y, target.width, target.height))
108− }
109−}
qml/Stages/WindowResizeArea.qmlnew file+215
@@ -0,0 +1,215 @@
1+/*
2+ * Copyright (C) 2014-2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Utils 0.1
20+import Unity.Application 0.1 // for Mir.cursorName
21+
22+MouseArea {
23+ id: root
24+ anchors.fill: target
25+ anchors.margins: -borderThickness
26+
27+ hoverEnabled: true
28+
29+ property var windowStateStorage: WindowStateStorage
30+
31+ // The target item managed by this. Must be a parent or a sibling
32+ // The area will anchor to it and manage move and resize events
33+ property Item target: null
34+ property string windowId: ""
35+ property int borderThickness: 0
36+ property int minWidth: 0
37+ property int minHeight: 0
38+
39+ QtObject {
40+ id: priv
41+ objectName: "priv"
42+
43+ property int normalX: 0
44+ property int normalY: 0
45+ property int normalWidth: 0
46+ property int normalHeight: 0
47+
48+ function updateNormalGeometry() {
49+ if (root.target.state == "normal") {
50+ normalX = root.target.x
51+ normalY = root.target.y
52+ normalWidth = root.target.width
53+ normalHeight = root.target.height
54+ }
55+ }
56+ }
57+
58+ Connections {
59+ target: root.target
60+ onXChanged: priv.updateNormalGeometry();
61+ onYChanged: priv.updateNormalGeometry();
62+ onWidthChanged: priv.updateNormalGeometry();
63+ onHeightChanged: priv.updateNormalGeometry();
64+ }
65+
66+ Component.onCompleted: {
67+ var windowGeometry = windowStateStorage.getGeometry(root.windowId, Qt.rect(target.x, target.y, target.width, target.height))
68+ if (windowGeometry !== undefined) {
69+ target.x = windowGeometry.x
70+ target.y = windowGeometry.y
71+ target.width = windowGeometry.width
72+ target.height = windowGeometry.height
73+ }
74+ var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal)
75+ if (windowState === WindowStateStorage.WindowStateMaximized) {
76+ target.maximize(false)
77+ }
78+ priv.updateNormalGeometry();
79+ }
80+
81+ Component.onDestruction: {
82+ windowStateStorage.saveState(root.windowId, target.state == "maximized" ? WindowStateStorage.WindowStateMaximized : WindowStateStorage.WindowStateNormal)
83+ windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight))
84+ }
85+
86+ QtObject {
87+ id: d
88+ property bool leftBorder: false
89+ property bool rightBorder: false
90+ property bool topBorder: false
91+ property bool bottomBorder: false
92+
93+ property bool dragging: false
94+ property real startMousePosX
95+ property real startMousePosY
96+ property real startX
97+ property real startY
98+ property real startWidth
99+ property real startHeight
100+
101+ property string cursorName: {
102+ if (root.containsMouse || root.pressed) {
103+ if (leftBorder && !topBorder && !bottomBorder) {
104+ return "left_side";
105+ } else if (rightBorder && !topBorder && !bottomBorder) {
106+ return "right_side";
107+ } else if (topBorder && !leftBorder && !rightBorder) {
108+ return "top_side";
109+ } else if (bottomBorder && !leftBorder && !rightBorder) {
110+ return "bottom_side";
111+ } else if (leftBorder && topBorder) {
112+ return "top_left_corner";
113+ } else if (leftBorder && bottomBorder) {
114+ return "bottom_left_corner";
115+ } else if (rightBorder && topBorder) {
116+ return "top_right_corner";
117+ } else if (rightBorder && bottomBorder) {
118+ return "bottom_right_corner";
119+ } else {
120+ return "";
121+ }
122+ } else {
123+ return "";
124+ }
125+ }
126+ onCursorNameChanged: {
127+ Mir.cursorName = cursorName;
128+ }
129+
130+ function updateBorders() {
131+ leftBorder = mouseX <= borderThickness;
132+ rightBorder = mouseX >= width - borderThickness;
133+ topBorder = mouseY <= borderThickness;
134+ bottomBorder = mouseY >= height - borderThickness;
135+ }
136+ }
137+
138+ onPressedChanged: {
139+ var pos = mapToItem(target.parent, mouseX, mouseY);
140+
141+ if (pressed) {
142+ d.updateBorders();
143+ var pos = mapToItem(root.target.parent, mouseX, mouseY);
144+ d.startMousePosX = pos.x;
145+ d.startMousePosY = pos.y;
146+ d.startX = target.x;
147+ d.startY = target.y;
148+ d.startWidth = target.width;
149+ d.startHeight = target.height;
150+ d.dragging = true;
151+ } else {
152+ d.dragging = false;
153+ if (containsMouse) {
154+ d.updateBorders();
155+ }
156+ }
157+ }
158+
159+ onEntered: {
160+ if (!pressed) {
161+ d.updateBorders();
162+ }
163+ }
164+
165+ onPositionChanged: {
166+ if (!pressed) {
167+ d.updateBorders();
168+ }
169+
170+ if (!d.dragging) {
171+ return;
172+ }
173+
174+ var pos = mapToItem(target.parent, mouse.x, mouse.y);
175+
176+ var deltaX = pos.x - d.startMousePosX;
177+ var deltaY = pos.y - d.startMousePosY;
178+
179+ if (d.leftBorder) {
180+ var newTargetX = d.startX + deltaX;
181+ if (target.x + target.width > newTargetX + minWidth) {
182+ target.width = target.x + target.width - newTargetX;
183+ target.x = newTargetX;
184+ } else {
185+ target.x = target.x + target.width - minWidth;
186+ target.width = minWidth;
187+ }
188+
189+ } else if (d.rightBorder) {
190+ if (d.startWidth + deltaX >= minWidth) {
191+ target.width = d.startWidth + deltaX;
192+ } else {
193+ target.width = minWidth;
194+ }
195+ }
196+
197+ if (d.topBorder) {
198+ var newTargetY = d.startY + deltaY;
199+ if (target.y + target.height > newTargetY + minHeight) {
200+ target.height = target.y + target.height - newTargetY;
201+ target.y = newTargetY;
202+ } else {
203+ target.y = target.y + target.height - minHeight;
204+ target.height = minHeight;
205+ }
206+
207+ } else if (d.bottomBorder) {
208+ if (d.startHeight + deltaY >= minHeight) {
209+ target.height = d.startHeight + deltaY;
210+ } else {
211+ target.height = minHeight;
212+ }
213+ }
214+ }
215+}
qml/Stages/graphics/background_paper@27.pngdeleted

Binary file not shown.

qml/Tutorial/Arrow.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: root
qml/Tutorial/Slider.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: root
qml/Tutorial/Tick.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020MouseArea {
2121 implicitHeight: tick.height
qml/Tutorial/Tutorial.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: root
qml/Tutorial/TutorialBottom.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import "../Components"
2121import "." as LocalComponents
qml/Tutorial/TutorialBottomFinish.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "." as LocalComponents
2020
2121TutorialPage {
qml/Tutorial/TutorialContent.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 id: root
qml/Tutorial/TutorialLeft.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "." as LocalComponents
2020
2121TutorialPage {
qml/Tutorial/TutorialLeftFinish.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "." as LocalComponents
2020
2121TutorialPage {
qml/Tutorial/TutorialPage.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121Showable {
qml/Tutorial/TutorialRight.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import Unity.Application 0.1
2121import "../Components"
qml/Wizard/CheckableSetting.qml+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.ListItems 1.0 as ListItem
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItem
2020
2121ListItem.Empty {
2222 id: listItem
@@ -77,7 +77,7 @@ ListItem.Empty {
7777 rightMargin: listItem.rightMargin
7878 }
7979 wrapMode: Text.Wrap
80− linkColor: Theme.palette.normal.foregroundText
80+ linkColor: theme.palette.normal.foregroundText
8181 onLinkActivated: listItem.linkActivated(link)
8282 }
8383 }
qml/Wizard/Page.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020Item {
2121 readonly property real buttonMargin: units.gu(2)
@@ -57,7 +57,7 @@ Item {
5757 }
5858 wrapMode: Text.Wrap
5959 text: title
60− color: Theme.palette.normal.baseText
60+ color: theme.palette.normal.baseText
6161 font.pixelSize: units.gu(4)
6262 }
6363
qml/Wizard/Pages.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.SystemSettings.SecurityPrivacy 1.0
2020import Wizard 0.1
2121import "../Components"
qml/Wizard/Pages/10-welcome.qml+3−3
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.ListItems 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3
2020import Ubuntu.SystemSettings.LanguagePlugin 1.0
2121import Wizard 0.1
2222import ".." as LocalComponents
qml/Wizard/Pages/20-sim.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import MeeGo.QOfono 0.2
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import ".." as LocalComponents
2121
2222LocalComponents.Page {
qml/Wizard/Pages/30-passwd-type.qml+7−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
19−import Ubuntu.Components.ListItems 1.0
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3
2020import Ubuntu.SystemSettings.SecurityPrivacy 1.0
2121import ".." as LocalComponents
2222
@@ -111,13 +111,13 @@ LocalComponents.Page {
111111
112112 Component.onCompleted: {
113113 // A visible selected background looks bad in ListItem widgets with our theme
114− originalBackground = Theme.palette.selected.background
115− Theme.palette.selected.background = "transparent"
114+ originalBackground = theme.palette.selected.background
115+ theme.palette.selected.background = "transparent"
116116 }
117117
118118 Component.onDestruction: {
119119 // Restore original theme background
120− Theme.palette.selected.background = originalBackground
120+ theme.palette.selected.background = originalBackground
121121 }
122122 }
123123 }
qml/Wizard/Pages/40-wifi.qml+3−3
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QMenuModel 0.1 as QMenuModel
1919import QtSystemInfo 5.0
20−import Ubuntu.Components 0.1
21−import Ubuntu.Components.ListItems 0.1 as ListItem
20+import Ubuntu.Components 1.3
21+import Ubuntu.Components.ListItems 1.3 as ListItem
2222import Ubuntu.Settings.Menus 0.1 as Menus
2323import ".." as LocalComponents
2424
qml/Wizard/Pages/50-location.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013,2014 Canonical, Ltd.
2+ * Copyright (C) 2013-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import AccountsService 0.1
1919import QMenuModel 0.1 as QMenuModel
2020import Qt.labs.folderlistmodel 2.1
21−import Ubuntu.Components 1.1
21+import Ubuntu.Components 1.3
2222import ".." as LocalComponents
2323
2424LocalComponents.Page {
@@ -98,7 +98,7 @@ LocalComponents.Page {
9898 anchors.leftMargin: hereCheck.labelOffset
9999 anchors.right: parent.right
100100 wrapMode: Text.Wrap
101− linkColor: Theme.palette.normal.foregroundText
101+ linkColor: theme.palette.normal.foregroundText
102102 // Translators: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
103103 text: i18n.tr("By selecting this option you agree to the Nokia HERE <a href='#'>terms and conditions</a>.")
104104 onLinkActivated: pageStack.load(Qt.resolvedUrl("here-terms.qml"))
qml/Wizard/Pages/60-reporting.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.SystemSettings.Diagnostics 1.0
2020import ".." as LocalComponents
2121
qml/Wizard/Pages/80-finished.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import ".." as LocalComponents
2020
2121LocalComponents.Page {
qml/Wizard/Pages/here-terms.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import AccountsService 0.1
1919import Qt.labs.folderlistmodel 2.1
20−import Ubuntu.Components 1.1
20+import Ubuntu.Components 1.3
2121import Ubuntu.Web 0.2
2222import ".." as LocalComponents
2323
@@ -102,7 +102,7 @@ LocalComponents.Page {
102102 anchors.left: parent.left
103103 anchors.right: parent.right
104104 wrapMode: Text.Wrap
105− linkColor: Theme.palette.normal.foregroundText
105+ linkColor: theme.palette.normal.foregroundText
106106 onLinkActivated: {
107107 webview.url = link
108108 termsLabel.visible = false
qml/Wizard/Pages/passwd-confirm.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.SystemSettings.SecurityPrivacy 1.0
2020import ".." as LocalComponents
2121import "../../Components" as UnityComponents
qml/Wizard/Pages/passwd-set.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.SystemSettings.SecurityPrivacy 1.0
2020import ".." as LocalComponents
2121import "../../Components" as UnityComponents
qml/Wizard/StackButton.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919
2020AbstractButton {
2121 id: stackButton
@@ -32,7 +32,7 @@ AbstractButton {
3232 anchors.verticalCenter: parent.verticalCenter
3333 anchors.left: parent.left
3434 anchors.right: parent.right
35− color: enabled ? Theme.palette.selected.backgroundText : Qt.darker(Theme.palette.selected.backgroundText, 1.5)
35+ color: enabled ? theme.palette.selected.backgroundText : Qt.darker(theme.palette.selected.backgroundText, 1.5)
3636 text: {
3737 if (backArrow) {
3838 // Translators: This is the arrow for "Back" buttons
qml/Wizard/Wizard.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Wizard 0.1
2020import "../Components"
2121
qml/graphics/applicationIcons/libreoffice@18.pngnew file

Binary file not shown.

src/ApplicationArguments.h+10−2
@@ -26,17 +26,25 @@
2626class ApplicationArguments : public QObject
2727{
2828 Q_OBJECT
29− Q_PROPERTY(QString deviceName READ deviceName CONSTANT)
29+ Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceNameChanged)
3030 Q_PROPERTY(QString mode READ mode CONSTANT)
3131public:
3232 ApplicationArguments(QObject *parent = nullptr);
3333
34− void setDeviceName(const QString &deviceName) { m_deviceName = deviceName; }
34+ void setDeviceName(const QString &deviceName) {
35+ if (deviceName != m_deviceName) {
36+ m_deviceName = deviceName;
37+ Q_EMIT deviceNameChanged(m_deviceName);
38+ }
39+ }
3540 QString deviceName() const { return m_deviceName; }
3641
3742 void setMode(const QString &mode) { m_mode = mode; }
3843 QString mode() const { return m_mode; }
3944
45+Q_SIGNALS:
46+ void deviceNameChanged(const QString&);
47+
4048private:
4149 QString m_deviceName;
4250 QString m_mode;
src/CMakeLists.txt+3
@@ -21,6 +21,9 @@ add_executable(${SHELL_APP}
2121 main.cpp
2222 MouseTouchAdaptor.cpp
2323 CachingNetworkManagerFactory.cpp
24+ SecondaryWindow.cpp
25+ ShellApplication.cpp
26+ ShellView.cpp
2427 UnityCommandLineParser.cpp
2528 ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
2629)
src/SecondaryWindow.cppnew file+31
@@ -0,0 +1,31 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "SecondaryWindow.h"
18+
19+// local
20+#include <paths.h>
21+
22+SecondaryWindow::SecondaryWindow(QQmlEngine *engine)
23+ : QQuickView(engine, nullptr)
24+{
25+ setResizeMode(QQuickView::SizeRootObjectToView);
26+ setColor("black");
27+ setTitle(QStringLiteral("Unity8 Shell - Secondary Screen"));
28+
29+ QUrl source(::qmlDirectory() + "/DisabledScreenNotice.qml");
30+ setSource(source);
31+}
src/SecondaryWindow.hnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UNITY_SECONDARY_WINDOW_H
18+#define UNITY_SECONDARY_WINDOW_H
19+
20+#include <QQuickView>
21+
22+class SecondaryWindow : public QQuickView
23+{
24+ Q_OBJECT
25+
26+public:
27+ SecondaryWindow(QQmlEngine *engine);
28+};
29+
30+#endif // UNITY_SECONDARY_WINDOW_H
src/ShellApplication.cppnew file+197
@@ -0,0 +1,197 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "ShellApplication.h"
18+
19+// Qt
20+#include <QLibrary>
21+#include <QScreen>
22+
23+#include <libintl.h>
24+
25+// libandroid-properties
26+#include <hybris/properties/properties.h>
27+
28+// local
29+#include <paths.h>
30+#include "CachingNetworkManagerFactory.h"
31+#include "MouseTouchAdaptor.h"
32+#include "UnityCommandLineParser.h"
33+
34+ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
35+ : QGuiApplication(argc, argv)
36+ , m_shellView(nullptr)
37+ , m_secondaryWindow(nullptr)
38+ , m_mouseTouchAdaptor(nullptr)
39+ , m_qmlEngine(nullptr)
40+{
41+
42+ setApplicationName(QStringLiteral("unity8"));
43+
44+ connect(this, &QGuiApplication::screenAdded, this, &ShellApplication::onScreenAdded);
45+
46+ setupQmlEngine(isMirServer);
47+
48+ UnityCommandLineParser parser(*this);
49+
50+ if (!parser.deviceName().isEmpty()) {
51+ m_deviceName = parser.deviceName();
52+ } else {
53+ char buffer[200];
54+ property_get("ro.product.device", buffer /* value */, "desktop" /* default_value*/);
55+ m_deviceName = QString(buffer);
56+ }
57+ m_qmlArgs.setDeviceName(m_deviceName);
58+
59+ m_qmlArgs.setMode(parser.mode());
60+
61+ // The testability driver is only loaded by QApplication but not by QGuiApplication.
62+ // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
63+ if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {
64+ QLibrary testLib(QStringLiteral("qttestability"));
65+ if (testLib.load()) {
66+ typedef void (*TasInitialize)(void);
67+ TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
68+ if (initFunction) {
69+ initFunction();
70+ } else {
71+ qCritical("Library qttestability resolve failed!");
72+ }
73+ } else {
74+ qCritical("Library qttestability load failed!");
75+ }
76+ }
77+
78+ bindtextdomain("unity8", translationDirectory().toUtf8().data());
79+ textdomain("unity8");
80+
81+ m_shellView = new ShellView(m_qmlEngine, &m_qmlArgs);
82+
83+ if (parser.windowGeometry().isValid()) {
84+ m_shellView->setWidth(parser.windowGeometry().width());
85+ m_shellView->setHeight(parser.windowGeometry().height());
86+ }
87+
88+ if (parser.hasFrameless()) {
89+ m_shellView->setFlags(Qt::FramelessWindowHint);
90+ }
91+
92+ // You will need this if you want to interact with touch-only components using a mouse
93+ // Needed only when manually testing on a desktop.
94+ if (parser.hasMouseToTouch()) {
95+ m_mouseTouchAdaptor = MouseTouchAdaptor::instance();
96+ }
97+
98+
99+ // Some hard-coded policy for now.
100+ // NB: We don't support more than two screens at the moment
101+ //
102+ // TODO: Support an arbitrary number of screens and different policies
103+ // (eg cloned desktop, several desktops, etc)
104+ if (isMirServer && screens().count() == 2) {
105+ m_shellView->setScreen(screens().at(1));
106+ m_qmlArgs.setDeviceName("desktop");
107+
108+ m_secondaryWindow = new SecondaryWindow(m_qmlEngine);
109+ m_secondaryWindow->setScreen(screens().at(0));
110+ // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
111+ m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
112+ m_secondaryWindow->setVisible(true);
113+ }
114+
115+ if (isMirServer || parser.hasFullscreen()) {
116+ m_shellView->showFullScreen();
117+ } else {
118+ m_shellView->show();
119+ }
120+}
121+
122+ShellApplication::~ShellApplication()
123+{
124+ destroyResources();
125+}
126+
127+void ShellApplication::destroyResources()
128+{
129+ // Deletion order is important. Don't use QScopedPointers and the like
130+ // Otherwise the process will hang on shutdown (bug somewhere I guess).
131+ delete m_shellView;
132+ m_shellView = nullptr;
133+
134+ delete m_secondaryWindow;
135+ m_secondaryWindow = nullptr;
136+
137+ delete m_mouseTouchAdaptor;
138+ m_mouseTouchAdaptor = nullptr;
139+
140+ delete m_qmlEngine;
141+ m_qmlEngine = nullptr;
142+}
143+
144+void ShellApplication::setupQmlEngine(bool isMirServer)
145+{
146+ m_qmlEngine = new QQmlEngine(this);
147+
148+ m_qmlEngine->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
149+
150+ prependImportPaths(m_qmlEngine, ::overrideImportPaths());
151+ if (!isMirServer) {
152+ prependImportPaths(m_qmlEngine, ::nonMirImportPaths());
153+ }
154+ appendImportPaths(m_qmlEngine, ::fallbackImportPaths());
155+
156+ m_qmlEngine->setNetworkAccessManagerFactory(new CachingNetworkManagerFactory);
157+
158+ QObject::connect(m_qmlEngine, &QQmlEngine::quit, this, &QGuiApplication::quit);
159+}
160+
161+void ShellApplication::onScreenAdded(QScreen * /*screen*/)
162+{
163+ // TODO: Support an arbitrary number of screens and different policies
164+ // (eg cloned desktop, several desktops, etc)
165+ if (screens().count() == 2) {
166+ m_shellView->setScreen(screens().at(1));
167+ m_qmlArgs.setDeviceName("desktop");
168+ // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
169+ // its backing QPlatformWindow recreated). So lets refocus it.
170+ m_shellView->requestActivate();
171+
172+ m_secondaryWindow = new SecondaryWindow(m_qmlEngine);
173+ m_secondaryWindow->setScreen(screens().at(0));
174+
175+ // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
176+ m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
177+ m_secondaryWindow->setVisible(true);
178+ }
179+}
180+
181+void ShellApplication::onScreenAboutToBeRemoved(QScreen *screen)
182+{
183+ // TODO: Support an arbitrary number of screens and different policies
184+ // (eg cloned desktop, several desktops, etc)
185+ if (screen == m_shellView->screen()) {
186+ Q_ASSERT(screens().count() > 1);
187+ Q_ASSERT(screens().at(0) != screen);
188+ Q_ASSERT(m_secondaryWindow);
189+ delete m_secondaryWindow;
190+ m_secondaryWindow = nullptr;
191+ m_shellView->setScreen(screens().first());
192+ m_qmlArgs.setDeviceName(m_deviceName);
193+ // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
194+ // its backing QPlatformWindow recreated). So lets refocus it.
195+ m_shellView->requestActivate();
196+ }
197+}
src/ShellApplication.hnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef SHELLAPPLICATION_H
18+#define SHELLAPPLICATION_H
19+
20+#include <QGuiApplication>
21+#include <QQmlEngine>
22+#include <QQuickView>
23+#include <QScopedPointer>
24+
25+#include "ApplicationArguments.h"
26+#include "MouseTouchAdaptor.h"
27+#include "SecondaryWindow.h"
28+#include "ShellView.h"
29+
30+class ShellApplication : public QGuiApplication
31+{
32+ Q_OBJECT
33+public:
34+ ShellApplication(int & argc, char ** argv, bool isMirServer);
35+ virtual ~ShellApplication();
36+
37+ void destroyResources();
38+public Q_SLOTS:
39+ // called by qtmir
40+ void onScreenAboutToBeRemoved(QScreen *screen);
41+
42+private Q_SLOTS:
43+ void onScreenAdded(QScreen*);
44+
45+private:
46+ void setupQmlEngine(bool isMirServer);
47+ QString m_deviceName;
48+ ApplicationArguments m_qmlArgs;
49+ ShellView *m_shellView;
50+ SecondaryWindow *m_secondaryWindow;
51+ MouseTouchAdaptor *m_mouseTouchAdaptor;
52+ QQmlEngine *m_qmlEngine;
53+};
54+
55+#endif // SHELLAPPLICATION_H
src/ShellView.cppnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "ShellView.h"
18+
19+// Qt
20+#include <QQmlContext>
21+#include <QQuickItem>
22+
23+// local
24+#include <paths.h>
25+
26+ShellView::ShellView(QQmlEngine *engine, QObject *qmlArgs)
27+ : QQuickView(engine, nullptr)
28+{
29+ setResizeMode(QQuickView::SizeRootObjectToView);
30+ setColor("black");
31+ setTitle(QStringLiteral("Unity8"));
32+
33+ rootContext()->setContextProperty(QStringLiteral("applicationArguments"), qmlArgs);
34+
35+ QUrl source(::qmlDirectory() + "/OrientedShell.qml");
36+ setSource(source);
37+
38+ connect(this, &QWindow::widthChanged, this, &ShellView::onWidthChanged);
39+ connect(this, &QWindow::heightChanged, this, &ShellView::onHeightChanged);
40+}
41+
42+void ShellView::onWidthChanged(int w)
43+{
44+ // For good measure in case SizeRootObjectToView doesn't fulfill its promise.
45+ //
46+ // There's at least one situation that's know to leave the root object with an outdated size.
47+ // (really looks like Qt bug)
48+ // Happens when starting unity8 with an external monitor already connected.
49+ // The QResizeEvent we get still has the size of the first screen and since the resize move is triggered
50+ // from the resize event handler, the root item doesn't get resized.
51+ // TODO: Confirm the Qt bug and submit a patch upstream
52+ rootObject()->setWidth(w);
53+}
54+
55+void ShellView::onHeightChanged(int h)
56+{
57+ // See comment in ShellView::onWidthChanged()
58+ rootObject()->setHeight(h);
59+}
src/ShellView.hnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UNITY_SHELL_VIEW_H
18+#define UNITY_SHELL_VIEW_H
19+
20+#include <QQuickView>
21+
22+class ShellView : public QQuickView
23+{
24+ Q_OBJECT
25+
26+public:
27+ ShellView(QQmlEngine *engine, QObject *qmlArgs);
28+
29+private Q_SLOTS:
30+ void onWidthChanged(int);
31+ void onHeightChanged(int);
32+};
33+
34+#endif // UNITY_SHELL_VIEW_H
src/main.cpp+4−101
@@ -14,26 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−// Qt
18−#include <QCommandLineParser>
19−#include <QtQuick/QQuickView>
20−#include <QtGui/QGuiApplication>
21−#include <QtQml/QQmlEngine>
22−#include <QtQml/QQmlContext>
23−#include <QLibrary>
24−#include <QDebug>
25−#include <csignal>
26−#include <libintl.h>
27−
28−// libandroid-properties
29−#include <hybris/properties/properties.h>
30−
3117// local
32−#include <paths.h>
33−#include "MouseTouchAdaptor.h"
34−#include "ApplicationArguments.h"
35−#include "CachingNetworkManagerFactory.h"
36−#include "UnityCommandLineParser.h"
18+#include "ShellApplication.h"
3719
3820int main(int argc, const char *argv[])
3921{
@@ -43,91 +25,12 @@ int main(int argc, const char *argv[])
4325 isMirServer = true;
4426 }
4527
46− QGuiApplication::setApplicationName(QStringLiteral("unity8"));
47− QGuiApplication *application;
48−
49− application = new QGuiApplication(argc, (char**)argv);
50−
51− UnityCommandLineParser parser(*application);
52−
53− ApplicationArguments qmlArgs;
54−
55− if (!parser.deviceName().isEmpty()) {
56− qmlArgs.setDeviceName(parser.deviceName());
57− } else {
58− char buffer[200];
59− property_get("ro.product.device", buffer /* value */, "desktop" /* default_value*/);
60− qmlArgs.setDeviceName(QString(buffer));
61− }
62−
63− qmlArgs.setMode(parser.mode());
64−
65− // The testability driver is only loaded by QApplication but not by QGuiApplication.
66− // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
67− if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {
68− QLibrary testLib(QStringLiteral("qttestability"));
69− if (testLib.load()) {
70− typedef void (*TasInitialize)(void);
71− TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
72− if (initFunction) {
73− initFunction();
74− } else {
75− qCritical("Library qttestability resolve failed!");
76− }
77− } else {
78− qCritical("Library qttestability load failed!");
79− }
80− }
81−
82− bindtextdomain("unity8", translationDirectory().toUtf8().data());
83− textdomain("unity8");
84−
85− QQuickView* view = new QQuickView();
86− view->setResizeMode(QQuickView::SizeRootObjectToView);
87− view->setColor("black");
88− view->setTitle(QStringLiteral("Unity8 Shell"));
89−
90− if (parser.windowGeometry().isValid()) {
91− view->setWidth(parser.windowGeometry().width());
92− view->setHeight(parser.windowGeometry().height());
93− }
94−
95− view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
96− view->rootContext()->setContextProperty(QStringLiteral("applicationArguments"), &qmlArgs);
97− if (parser.hasFrameless()) {
98− view->setFlags(Qt::FramelessWindowHint);
99− }
100−
101− // You will need this if you want to interact with touch-only components using a mouse
102− // Needed only when manually testing on a desktop.
103− MouseTouchAdaptor *mouseTouchAdaptor = 0;
104− if (parser.hasMouseToTouch()) {
105− mouseTouchAdaptor = MouseTouchAdaptor::instance();
106− }
107−
108− QUrl source(::qmlDirectory() + "/OrientedShell.qml");
109− prependImportPaths(view->engine(), ::overrideImportPaths());
110− if (!isMirServer) {
111− prependImportPaths(view->engine(), ::nonMirImportPaths());
112− }
113− appendImportPaths(view->engine(), ::fallbackImportPaths());
114−
115− CachingNetworkManagerFactory *managerFactory = new CachingNetworkManagerFactory();
116− view->engine()->setNetworkAccessManagerFactory(managerFactory);
117−
118− view->setSource(source);
119− QObject::connect(view->engine(), &QQmlEngine::quit, application, &QGuiApplication::quit);
120−
121− if (isMirServer || parser.hasFullscreen()) {
122− view->showFullScreen();
123− } else {
124− view->show();
125− }
28+ ShellApplication *application = new ShellApplication(argc, (char**)argv, isMirServer);
12629
12730 int result = application->exec();
12831
129− delete view;
130− delete mouseTouchAdaptor;
32+ application->destroyResources();
33+
13134 delete application;
13235
13336 return result;
tests/CMakeLists.txt+1
@@ -132,3 +132,4 @@ add_subdirectory(libs)
132132add_subdirectory(plugins)
133133add_subdirectory(qmltests)
134134add_subdirectory(whitespace)
135+add_subdirectory(imports)
tests/autopilot/unity8/dash.py+3−3
@@ -158,7 +158,7 @@ class Dash(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
158158 def enter_search_query(self, query, keyboard):
159159 current_header = self._get_current_page_header()
160160 search_button = \
161− current_header.select_single(objectName="search_header_button")
161+ current_header.select_single(objectName="search_action_button")
162162 self.pointing_device.move(
163163 search_button.globalRect.x + search_button.width / 2,
164164 search_button.globalRect.y + search_button.height / 2)
@@ -224,7 +224,7 @@ class GenericScopeView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
224224 """
225225 category_element = self._get_category_element(category)
226226 icon = category_element.wait_select_single(
227− 'AbstractButton', title=title)
227+ 'UCAbstractButton', title=title)
228228 list_view = self.select_single(
229229 ListViewWithPageHeader, objectName='categoryListView')
230230 list_view.swipe_child_into_view(icon)
@@ -247,7 +247,7 @@ class GenericScopeView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
247247 """
248248 category_element = self._get_category_element(category)
249249 see_all = category_element.select_single(objectName='seeAll')
250− application_cards = category_element.select_many('AbstractButton')
250+ application_cards = category_element.select_many('UCAbstractButton')
251251
252252 application_cards = sorted(
253253 (card for card in application_cards
tests/autopilot/unity8/fixture_setup.py+1−1
@@ -133,7 +133,7 @@ class LaunchUnityWithFakeSensors(fixtures.Fixture):
133133 args = [binary_arg] + env_args
134134 self.unity_proxy = process_helpers.restart_unity_with_testability(
135135 *args)
136− self.main_win = self.unity_proxy.select_single(shell.QQuickView)
136+ self.main_win = self.unity_proxy.select_single(shell.ShellView)
137137
138138 def _create_sensors(self):
139139 # Wait for unity to start running.
tests/autopilot/unity8/greeter/tests/__init__.py+1−1
@@ -24,5 +24,5 @@ from unity8.shell.tests import UnityTestCase
2424class GreeterTestCase(UnityTestCase):
2525 def get_shell(self, unity_proxy):
2626 main_window = (
27− unity_proxy.select_single(shell.QQuickView))
27+ unity_proxy.select_single(shell.ShellView))
2828 return main_window.select_single('Shell')
tests/autopilot/unity8/launcher.py+1−1
@@ -42,7 +42,7 @@ class Launcher(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
4242 logger.debug('The launcher is already opened.')
4343
4444 def _swipe_to_show_launcher(self):
45− view = self.get_root_instance().select_single('QQuickView')
45+ view = self.get_root_instance().select_single('ShellView')
4646 start_y = stop_y = view.y + view.height // 2
4747
4848 start_x = view.x + 1
tests/autopilot/unity8/process_helpers.py+1−1
@@ -146,7 +146,7 @@ def stop_job(name):
146146 :raises CalledProcessError: if the job failed to stop.
147147
148148 """
149− logger.info('Stoping job {}.'.format(name))
149+ logger.info('Stopping job {}.'.format(name))
150150 command = ['/sbin/initctl', 'stop', name]
151151 try:
152152 output = subprocess.check_output(
tests/autopilot/unity8/settings_wizard/__init__.py+7−2
@@ -375,12 +375,17 @@ class WifiConnectPage(UbuntuUIToolkitCustomProxyObjectBase):
375375 wizard = get_wizard(self)
376376 next_page = wizard.get_current_page()
377377 locationPageEnabled = True
378+ reportingPageEnabled = True
378379 if next_page.objectName == 'locationPage':
379380 next_page = wizard.get_location_page()
380381 else:
381382 locationPageEnabled = False
382− next_page = wizard.get_reporting_page()
383− return locationPageEnabled, next_page
383+ if next_page.objectName == 'reportingPage':
384+ next_page = wizard.get_reporting_page()
385+ else:
386+ reportingPageEnabled = False
387+ next_page = wizard.get_finished_page()
388+ return locationPageEnabled, reportingPageEnabled, next_page
384389
385390 def _get_notification(self, unity):
386391 logger.info('Waiting longer for notification object')
tests/autopilot/unity8/settings_wizard/tests/test_settings_wizard.py+10−5
@@ -80,14 +80,19 @@ class SkipThroughSettingsWizardTestCase(tests.UnityTestCase):
8080 password_page = next_page
8181 wifi_connect_page = self._test_password_page(password_page)
8282
83− locationPageEnabled, next_page = self._test_wifi_connect_page(
84− wifi_connect_page)
83+ reporting_page = None
84+ locationPageEnabled, reportingPageEnabled, next_page = self._test_wifi_connect_page(wifi_connect_page)
8585 if locationPageEnabled:
8686 location_page = next_page
87− reporting_page = self._test_location_page(location_page)
87+ if reportingPageEnabled:
88+ reporting_page = self._test_location_page(location_page)
89+ else:
90+ finish_page = next_page
91+
92+ if reporting_page is not None:
93+ finish_page = self._test_reporting_page(reporting_page)
8894 else:
89− reporting_page = next_page
90− finish_page = self._test_reporting_page(reporting_page)
95+ finish_page = next_page
9196
9297 finish_page.finish()
9398 self.assertFalse(
tests/autopilot/unity8/shell/__init__.py+1−1
@@ -93,7 +93,7 @@ def _get_urgency(urgency):
9393 return _urgency_enums.get(urgency.upper())
9494
9595
96−class QQuickView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
96+class ShellView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
9797 """An helper class that makes it easy to interact with the shell"""
9898
9999 def get_greeter(self):
tests/autopilot/unity8/shell/tests/__init__.py+1−1
@@ -297,7 +297,7 @@ class UnityTestCase(AutopilotTestCase):
297297
298298 @property
299299 def main_window(self):
300− return self._proxy.select_single(shell.QQuickView)
300+ return self._proxy.select_single(shell.ShellView)
301301
302302
303303class DashBaseTestCase(AutopilotTestCase):
tests/imports/CMakeLists.txtnew file+5
@@ -0,0 +1,5 @@
1+
2+#
3+# Test that all imports for QtQuick and Ubuntu.Components use the wanted version
4+#
5+add_test(imports ${CMAKE_CURRENT_SOURCE_DIR}/check_imports.py ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
tests/imports/check_imports.pynew file+125
@@ -0,0 +1,125 @@
1+#! /usr/bin/env python3
2+
3+#
4+# Copyright (C) 2015 Canonical Ltd
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License version 3 as
8+# published by the Free Software Foundation.
9+#
10+# This program is distributed in the hope that it will be useful,
11+# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+# GNU General Public License for more details.
14+#
15+# You should have received a copy of the GNU General Public License
16+# along with this program. If not, see <http://www.gnu.org/licenses/>.
17+#
18+
19+#
20+# Little helper program to test that all source files import
21+# versions we want
22+#
23+# Usage: check_imports.py directory [ignore_prefix]
24+#
25+# The directory specifies the (recursive) location of the source files. Any
26+# files with a path that starts with ignore_prefix are not checked. This is
27+# useful to exclude files that are generated into the build directory.
28+#
29+# See the file_pat definition below for a list of files that are checked.
30+#
31+
32+from __future__ import print_function
33+
34+import argparse
35+import os
36+import re
37+import sys
38+
39+
40+# Print msg on stderr, preceded by program name and followed by newline
41+def error(msg):
42+ print(os.path.basename(sys.argv[0]) + ": " + msg, file=sys.stderr)
43+
44+
45+# Function to raise errors encountered by os.walk
46+def raise_error(e):
47+ raise e
48+
49+# Qt Quick patterns
50+# If you increase this make sure you increase
51+# the Qt version in debian/control and in CMakeLists.txt
52+quick_pat = re.compile(r'.*import QtQuick.*$')
53+quick_good_pat = re.compile(r'.*import QtQuick 2\.4.*$')
54+quick_layouts_good_pat = re.compile(r'.*import QtQuick.Layouts 1\.1.*$')
55+quick_window_good_pat = re.compile(r'.*import QtQuick.Window 2\.2.*$')
56+
57+# Ubuntu Components patterns
58+ubuntu_components_pat = re.compile(r'.*import Ubuntu.Components.*')
59+ubuntu_good_components_pat = re.compile(r'.*import Ubuntu.Components.*1\.3.*')
60+
61+def scan_for_bad_import(file_path, all_pat, good_pats):
62+ errors = []
63+ with open(file_path, 'rt', encoding='utf-8') as ifile:
64+ for lino, line in enumerate(ifile, start=1):
65+ if all_pat.match(line):
66+ good_found = False
67+ for good_pat in good_pats:
68+ if good_pat.match(line):
69+ good_found = True
70+ if not good_found:
71+ errors.append(lino)
72+ if 0 < len(errors) <= 10:
73+ if len(errors) > 1:
74+ plural = 's'
75+ else:
76+ plural = ''
77+ print(
78+ "%s: bad import version in line%s %s" % (
79+ file_path, plural, ", ".join((str(i) for i in errors))))
80+ elif errors:
81+ print("%s: bad import version in multiple lines" % file_path)
82+ return bool(errors)
83+
84+# Parse args
85+
86+parser = argparse.ArgumentParser(
87+ description='Test that source files contain the wanted import version.')
88+parser.add_argument(
89+ 'dir', nargs=1,
90+ help='The directory to (recursively) search for source files')
91+parser.add_argument(
92+ 'ignore_prefix', nargs='?', default=None,
93+ help='Ignore source files with a path that starts with the given prefix.')
94+args = parser.parse_args()
95+
96+# Files we want to check for import version.
97+
98+file_pat = (
99+ r'(.*\.(js|qml)$)')
100+pat = re.compile(file_pat)
101+
102+# Find all the files with matching file extension in the specified
103+# directory and check them
104+
105+directory = os.path.abspath(args.dir[0])
106+ignore = args.ignore_prefix and os.path.abspath(args.ignore_prefix) or None
107+
108+found_bad_import = False
109+try:
110+ for root, dirs, files in os.walk(directory, onerror=raise_error):
111+ for file in files:
112+ path = os.path.join(root, file)
113+ if not (ignore and path.startswith(ignore)) and pat.match(file):
114+ quick_good_pats = [quick_good_pat, quick_layouts_good_pat, quick_window_good_pat]
115+ if scan_for_bad_import(path, quick_pat, quick_good_pats):
116+ found_bad_import = True
117+ if scan_for_bad_import(path, ubuntu_components_pat, [ubuntu_good_components_pat]):
118+ found_bad_import = True
119+
120+except OSError as e:
121+ error("cannot create file list for \"" + dir + "\": " + e.strerror)
122+ sys.exit(1)
123+
124+if found_bad_import:
125+ sys.exit(1)
tests/mocks/CMakeLists.txt+1
@@ -29,6 +29,7 @@ macro(add_unity8_mock PLUGIN VERSION PATH)
2929endmacro()
3030
3131add_subdirectory(AccountsService)
32+add_subdirectory(Cursor)
3233add_subdirectory(GSettings.1.0)
3334add_subdirectory(indicator-service)
3435add_subdirectory(libusermetrics)
tests/mocks/Cursor/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_unity8_mock(Cursor 1.0 Cursor PREFIX mocks)
tests/mocks/Cursor/Cursor.qmlnew file+20
@@ -0,0 +1,20 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+
19+Item {
20+}
tests/mocks/Cursor/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Cursor
2+Cursor 1.0 Cursor.qml
tests/mocks/GSettings.1.0/fake_gsettings.cpp+31
@@ -75,6 +75,19 @@ void GSettingsControllerQml::setLockedOutTime(qint64 timestamp)
7575 }
7676}
7777
78+QStringList GSettingsControllerQml::lifecycleExemptAppids() const
79+{
80+ return m_lifecycleExemptAppids;
81+}
82+
83+void GSettingsControllerQml::setLifecycleExemptAppids(const QStringList &appIds)
84+{
85+ if (m_lifecycleExemptAppids != appIds) {
86+ m_lifecycleExemptAppids = appIds;
87+ Q_EMIT lifecycleExemptAppidsChanged(m_lifecycleExemptAppids);
88+ }
89+}
90+
7891GSettingsSchemaQml::GSettingsSchemaQml(QObject *parent): QObject(parent) {
7992}
8093
@@ -114,6 +127,8 @@ GSettingsQml::GSettingsQml(QObject *parent)
114127 this, &GSettingsQml::usageModeChanged);
115128 connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::lockedOutTimeChanged,
116129 this, &GSettingsQml::lockedOutTimeChanged);
130+ connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::lifecycleExemptAppidsChanged,
131+ this, &GSettingsQml::lifecycleExemptAppidsChanged);
117132}
118133
119134GSettingsSchemaQml * GSettingsQml::schema() const {
@@ -167,3 +182,19 @@ void GSettingsQml::setLockedOutTime(qint64 timestamp)
167182 GSettingsControllerQml::instance()->setLockedOutTime(timestamp);
168183 }
169184}
185+
186+QStringList GSettingsQml::lifecycleExemptAppids() const
187+{
188+ if (m_schema->id() == "com.canonical.qtmir") {
189+ return GSettingsControllerQml::instance()->lifecycleExemptAppids();
190+ } else {
191+ return QStringList();
192+ }
193+}
194+
195+void GSettingsQml::setLifecycleExemptAppids(const QStringList &appIds)
196+{
197+ if (m_schema->id() == "com.canonical.qtmir") {
198+ GSettingsControllerQml::instance()->setLifecycleExemptAppids(appIds);
199+ }
200+}
tests/mocks/GSettings.1.0/fake_gsettings.h+10
@@ -19,6 +19,7 @@
1919
2020#include <QList>
2121#include <QObject>
22+#include <QStringList>
2223
2324class GSettingsSchemaQml: public QObject
2425{
@@ -48,6 +49,7 @@ class GSettingsQml: public QObject
4849 Q_PROPERTY(QString pictureUri READ pictureUri WRITE setPictureUri NOTIFY pictureUriChanged)
4950 Q_PROPERTY(QString usageMode READ usageMode WRITE setUsageMode NOTIFY usageModeChanged)
5051 Q_PROPERTY(qint64 lockedOutTime READ lockedOutTime WRITE setLockedOutTime NOTIFY lockedOutTimeChanged)
52+ Q_PROPERTY(QStringList lifecycleExemptAppids READ lifecycleExemptAppids WRITE setLifecycleExemptAppids NOTIFY lifecycleExemptAppidsChanged)
5153
5254public:
5355 GSettingsQml(QObject *parent = nullptr);
@@ -56,16 +58,19 @@ public:
5658 QString pictureUri() const;
5759 QString usageMode() const;
5860 qint64 lockedOutTime() const;
61+ QStringList lifecycleExemptAppids() const;
5962
6063 void setPictureUri(const QString &str);
6164 void setUsageMode(const QString &usageMode);
6265 void setLockedOutTime(qint64 timestamp);
66+ void setLifecycleExemptAppids(const QStringList &appIds);
6367
6468Q_SIGNALS:
6569 void schemaChanged();
6670 void pictureUriChanged(const QString&);
6771 void usageModeChanged(const QString&);
6872 void lockedOutTimeChanged(qint64);
73+ void lifecycleExemptAppidsChanged(const QStringList &);
6974
7075private:
7176 GSettingsSchemaQml* m_schema;
@@ -90,10 +95,14 @@ public:
9095 qint64 lockedOutTime() const;
9196 Q_INVOKABLE void setLockedOutTime(qint64 timestamp);
9297
98+ QStringList lifecycleExemptAppids() const;
99+ Q_INVOKABLE void setLifecycleExemptAppids(const QStringList &appIds);
100+
93101Q_SIGNALS:
94102 void pictureUriChanged(const QString&);
95103 void usageModeChanged(const QString&);
96104 void lockedOutTimeChanged(qint64 timestamp);
105+ void lifecycleExemptAppidsChanged(const QStringList&);
97106
98107private:
99108 GSettingsControllerQml();
@@ -101,6 +110,7 @@ private:
101110 QString m_pictureUri;
102111 QString m_usageMode;
103112 qint64 m_lockedOutTime;
113+ QStringList m_lifecycleExemptAppids;
104114
105115 static GSettingsControllerQml* s_controllerInstance;
106116 QList<GSettingsQml *> m_registeredGSettings;
tests/mocks/MeeGo/QOfono/MockOfonoSimManager.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import MeeGo.QOfono 0.2
1919
2020Item {
tests/mocks/QMenuModel/QDBusActionGroup.qml+2−2
@@ -17,7 +17,7 @@
1717 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121import Ubuntu.Settings.Menus 0.1 as Menus
2222import QMenuModel 0.1
2323
@@ -34,7 +34,7 @@ QtObject {
3434
3535 function action(actionName) {
3636 return Qt.createQmlObject("
37− import QtQuick 2.3
37+ import QtQuick 2.4
3838 import QMenuModel 0.1
3939
4040 QtObject {
tests/mocks/QMenuModel/UnityMenuAction.qml+1−1
@@ -17,7 +17,7 @@
1717 * Nick Dedekind <nick.dedekind@canonical.com>
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121import QMenuModel 0.1
2222
2323QtObject {
tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockLanguagePlugin.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818
1919Item {
2020 property var languageNames: ["English", "French", "Spanish"]
tests/mocks/Ubuntu/Web/WebView.qml+1−1
@@ -15,7 +15,7 @@
1515 *
1616 */
1717
18−import QtQuick 2.0
18+import QtQuick 2.4
1919
2020Item {
2121 property url url
tests/mocks/Unity/Application/ApplicationInfo.cpp+12
@@ -41,6 +41,7 @@ ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent)
4141 Qt::InvertedLandscapeOrientation)
4242 , m_rotatesWindowContents(false)
4343 , m_requestedState(RequestedRunning)
44+ , m_isTouchApp(true)
4445 , m_manualSurfaceCreation(false)
4546{
4647}
@@ -58,6 +59,7 @@ ApplicationInfo::ApplicationInfo(QObject *parent)
5859 Qt::InvertedLandscapeOrientation)
5960 , m_rotatesWindowContents(false)
6061 , m_requestedState(RequestedRunning)
62+ , m_isTouchApp(true)
6163 , m_manualSurfaceCreation(false)
6264{
6365}
@@ -245,6 +247,16 @@ void ApplicationInfo::setRequestedState(RequestedState value)
245247 }
246248}
247249
250+bool ApplicationInfo::isTouchApp() const
251+{
252+ return m_isTouchApp;
253+}
254+
255+void ApplicationInfo::setIsTouchApp(bool isTouchApp)
256+{
257+ m_isTouchApp = isTouchApp;
258+}
259+
248260void ApplicationInfo::onSessionSurfaceChanged(MirSurface* surface)
249261{
250262 if (surface != nullptr && m_state == Starting) {
tests/mocks/Unity/Application/ApplicationInfo.h+4
@@ -89,6 +89,9 @@ public:
8989 bool manualSurfaceCreation() const { return m_manualSurfaceCreation; }
9090 void setManualSurfaceCreation(bool value);
9191
92+ bool isTouchApp() const override;
93+ void setIsTouchApp(bool isTouchApp); // only in mock
94+
9295public:
9396 void setSession(Session* session);
9497 Session* session() const { return m_session; }
@@ -121,6 +124,7 @@ private:
121124 Qt::ScreenOrientations m_supportedOrientations;
122125 bool m_rotatesWindowContents;
123126 RequestedState m_requestedState;
127+ bool m_isTouchApp;
124128
125129 bool m_manualSurfaceCreation;
126130};
tests/mocks/Unity/Application/ApplicationManager.cpp+9
@@ -105,6 +105,8 @@ QVariant ApplicationManager::data(const QModelIndex& index, int role) const {
105105 return app->state();
106106 case RoleFocused:
107107 return app->focused();
108+ case RoleIsTouchApp:
109+ return app->isTouchApp();
108110 case RoleSession:
109111 return QVariant::fromValue(app->session());
110112 case RoleFullscreen:
@@ -458,6 +460,13 @@ void ApplicationManager::buildListOfAvailableApplications()
458460 application->setName("YouTube");
459461 application->setIconId("youtube");
460462 m_availableApplications.append(application);
463+
464+ application = new ApplicationInfo(this);
465+ application->setAppId("libreoffice");
466+ application->setName("LibreOffice");
467+ application->setIconId("libreoffice");
468+ application->setIsTouchApp(false);
469+ m_availableApplications.append(application);
461470}
462471
463472
tests/mocks/Unity/Application/ApplicationManager.h+1−1
@@ -43,7 +43,7 @@ class ApplicationManager : public ApplicationManagerInterface {
4343 static ApplicationManager *singleton();
4444
4545 enum MoreRoles {
46− RoleSession = RoleFocused+1,
46+ RoleSession = RoleIsTouchApp+1,
4747 RoleFullscreen,
4848 };
4949 enum Flag {
tests/mocks/Unity/Application/MirSurface.cpp+41−14
@@ -31,7 +31,7 @@ MirSurface::MirSurface(const QString& name,
3131 , m_screenshotUrl(screenshot)
3232 , m_qmlFilePath(qmlFilePath)
3333 , m_live(true)
34− , m_viewCount(0)
34+ , m_visible(true)
3535 , m_activeFocus(false)
3636 , m_width(-1)
3737 , m_height(-1)
@@ -73,6 +73,11 @@ bool MirSurface::live() const
7373 return m_live;
7474}
7575
76+bool MirSurface::visible() const
77+{
78+ return m_visible;
79+}
80+
7681void MirSurface::setLive(bool live)
7782{
7883// qDebug().nospace() << "MirSurface::setLive("<<live<<") " << name();
@@ -82,7 +87,7 @@ void MirSurface::setLive(bool live)
8287 m_live = live;
8388 Q_EMIT liveChanged(live);
8489
85− if (!m_live && m_viewCount == 0) {
90+ if (!m_live && m_views.count() == 0) {
8691 deleteLater();
8792 }
8893}
@@ -120,27 +125,49 @@ void MirSurface::setOrientationAngle(Mir::OrientationAngle angle)
120125 Q_EMIT orientationAngleChanged(angle);
121126}
122127
123−void MirSurface::incrementViewCount()
128+
129+
130+void MirSurface::registerView(qintptr viewId)
124131{
125− ++m_viewCount;
126−// qDebug().nospace() << "MirSurface::incrementViewCount() viewCount(after)=" << m_viewCount << " " << name();
132+ m_views.insert(viewId, MirSurface::View{false});
133+// qDebug().nospace() << "MirSurface[" << name() << "]::registerView(" << viewId << ")"
134+// << " after=" << m_views.count();
127135}
128136
129−void MirSurface::decrementViewCount()
137+void MirSurface::unregisterView(qintptr viewId)
130138{
131− --m_viewCount;
132−// qDebug().nospace() << "MirSurface::decrementViewCount() viewCount(after)=" << m_viewCount << " " << name();
133−
134− Q_ASSERT(m_viewCount >= 0);
135−
136− if (!m_live && m_viewCount == 0) {
139+// qDebug().nospace() << "MirSurface[" << name() << "]::unregisterView(" << viewId << ")"
140+// << " after=" << m_views.count() << " live=" << m_live;
141+ m_views.remove(viewId);
142+ if (!m_live && m_views.count() == 0) {
137143 deleteLater();
138144 }
145+ updateVisibility();
139146}
140147
141−int MirSurface::viewCount() const
148+void MirSurface::setViewVisibility(qintptr viewId, bool visible)
142149{
143− return m_viewCount;
150+ if (!m_views.contains(viewId)) return;
151+
152+ m_views[viewId].visible = visible;
153+ updateVisibility();
154+}
155+
156+void MirSurface::updateVisibility()
157+{
158+ bool newVisible = false;
159+ QHashIterator<qintptr, View> i(m_views);
160+ while (i.hasNext()) {
161+ i.next();
162+ newVisible |= i.value().visible;
163+ }
164+
165+ if (newVisible != visible()) {
166+// qDebug().nospace() << "MirSurface[" << name() << "]::updateVisibility(" << newVisible << ")";
167+
168+ m_visible = newVisible;
169+ Q_EMIT visibleChanged(m_visible);
170+ }
144171}
145172
146173bool MirSurface::activeFocus() const
tests/mocks/Unity/Application/MirSurface.h+14−4
@@ -19,6 +19,7 @@
1919
2020#include <QObject>
2121#include <QUrl>
22+#include <QHash>
2223
2324// unity-api
2425#include <unity/shell/application/MirSurfaceInterface.h>
@@ -58,6 +59,8 @@ public:
5859
5960 bool live() const override;
6061
62+ bool visible() const override;
63+
6164 Mir::OrientationAngle orientationAngle() const override;
6265 void setOrientationAngle(Mir::OrientationAngle) override;
6366
@@ -66,9 +69,10 @@ public:
6669
6770 Q_INVOKABLE void setLive(bool live);
6871
69− void incrementViewCount();
70− void decrementViewCount();
71− int viewCount() const;
72+ void registerView(qintptr viewId);
73+ void unregisterView(qintptr viewId);
74+ void setViewVisibility(qintptr viewId, bool visible);
75+ int viewCount() const { return m_views.count(); }
7276
7377 int width() const;
7478 int height() const;
@@ -97,6 +101,8 @@ Q_SIGNALS:
97101 void activeFocusChanged(bool);
98102
99103private:
104+ void updateVisibility();
105+
100106 const QString m_name;
101107 const Mir::Type m_type;
102108 Mir::State m_state;
@@ -104,10 +110,14 @@ private:
104110 QUrl m_screenshotUrl;
105111 QUrl m_qmlFilePath;
106112 bool m_live;
107− int m_viewCount;
113+ bool m_visible;
108114 bool m_activeFocus;
109115 int m_width;
110116 int m_height;
117+ struct View {
118+ bool visible;
119+ };
120+ QHash<qintptr, View> m_views;
111121};
112122
113123#endif // MOCK_MIR_SURFACE_H
tests/mocks/Unity/Application/MirSurfaceItem.cpp+12−2
@@ -44,6 +44,8 @@ MirSurfaceItem::MirSurfaceItem(QQuickItem *parent)
4444 Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 |
4545 Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 |
4646 Qt::ExtraButton12 | Qt::ExtraButton13);
47+
48+ connect(this, &QQuickItem::visibleChanged, this, &MirSurfaceItem::updateMirSurfaceVisibility);
4749}
4850
4951MirSurfaceItem::~MirSurfaceItem()
@@ -194,17 +196,18 @@ void MirSurfaceItem::setSurface(MirSurfaceInterface* surface)
194196 m_qmlContentComponent = nullptr;
195197
196198 disconnect(m_qmlSurface, nullptr, this, nullptr);
197− m_qmlSurface->decrementViewCount();
199+ m_qmlSurface->unregisterView((qintptr)this);
198200 }
199201
200202 m_qmlSurface = static_cast<MirSurface*>(surface);
201203
202204 if (m_qmlSurface) {
203− m_qmlSurface->incrementViewCount();
205+ m_qmlSurface->registerView((qintptr)this);
204206
205207 m_qmlSurface->setActiveFocus(hasActiveFocus());
206208
207209 updateSurfaceSize();
210+ updateMirSurfaceVisibility();
208211
209212 connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged);
210213 connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot);
@@ -253,6 +256,13 @@ void MirSurfaceItem::itemChange(ItemChange change, const ItemChangeData & value)
253256 }
254257}
255258
259+void MirSurfaceItem::updateMirSurfaceVisibility()
260+{
261+ if (!m_qmlSurface) return;
262+
263+ m_qmlSurface->setViewVisibility((qintptr)this, isVisible());
264+}
265+
256266void MirSurfaceItem::setConsumesInput(bool value)
257267{
258268 if (m_consumesInput != value) {
tests/mocks/Unity/Application/MirSurfaceItem.h+1
@@ -87,6 +87,7 @@ protected:
8787private Q_SLOTS:
8888 void onComponentStatusChanged(QQmlComponent::Status status);
8989 void updateScreenshot(QUrl screenshot);
90+ void updateMirSurfaceVisibility();
9091
9192private:
9293 void createQmlContentItem();
tests/mocks/Unity/Application/resources/MirSurfaceItem.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Rectangle {
2020 id: root
tests/mocks/Unity/Application/resources/VirtualKeyboard.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Unity.Application 0.1
1919
2020Item {
tests/mocks/Unity/Indicators/ActionRootState.qml+1−1
@@ -17,7 +17,7 @@
1717 * Nick Dedekind <nick.dedekind@canonical.com>
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121
2222QtObject {
2323 property var actionGroup
tests/mocks/Unity/Indicators/IndicatorsModel.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Unity.Indicators 0.1 as Indicators
1919
2020Indicators.FakeIndicatorsModel {
tests/mocks/Unity/Indicators/ModelActionRootState.qml+1−1
@@ -17,7 +17,7 @@
1717 * Nick Dedekind <nick.dedekind@canonical.com>
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121
2222Item {
2323 property var menu: null
tests/mocks/Unity/Launcher/MockQuickListModel.cpp+1−1
@@ -32,7 +32,7 @@ QVariant MockQuickListModel::data(const QModelIndex &index, int role) const
3232 switch (role)
3333 {
3434 case RoleLabel:
35− return QLatin1String("test menu entry ") + QString::number(index.row());
35+ return QString(QLatin1String("test menu entry ") + QString::number(index.row()));
3636 case RoleIcon:
3737 return QLatin1String("copy.png");
3838 case RoleClickable:
tests/mocks/Unity/fake_resultsmodel.cpp+1−1
@@ -78,7 +78,7 @@ ResultsModel::data(const QModelIndex& index, int role) const
7878 case RoleTitle:
7979 return QString("Title.%1.%2").arg(m_categoryId).arg(index.row());
8080 case RoleArt:
81− return qmlDirectory() + "/graphics/applicationIcons/dash.png";
81+ return QString(qmlDirectory() + "/graphics/applicationIcons/dash.png");
8282 case RoleSubtitle:
8383 return QString("Subtitle.%1.%2").arg(m_categoryId).arg(index.row());
8484 case RoleMascot:
tests/mocks/Unity/fake_scopesoverview.cpp+1−1
@@ -308,7 +308,7 @@ QVariant ScopesOverviewResultsModel::data(const QModelIndex& index, int role) co
308308 case RoleSubtitle:
309309 return scope && scope->name() == "Videos this is long ab cd ef gh ij kl" ? "tube, movies, cinema, pictures, art, moving images, magic in a box" : QString();
310310 case RoleArt:
311− return qmlDirectory() + "/graphics/applicationIcons/dash.png";
311+ return QString(qmlDirectory() + "/graphics/applicationIcons/dash.png");
312312 case RoleMascot:
313313 case RoleEmblem:
314314 case RoleSummary:
tests/mocks/Utils/CMakeLists.txt−2
@@ -13,8 +13,6 @@ set(QMLPLUGIN_SRC
1313 ${CMAKE_SOURCE_DIR}/plugins/Utils/activefocuslogger.cpp
1414 ${CMAKE_SOURCE_DIR}/plugins/Utils/qlimitproxymodelqml.cpp
1515 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
16− ${CMAKE_SOURCE_DIR}/plugins/Utils/relativetimeformatter.cpp
17− ${CMAKE_SOURCE_DIR}/plugins/Utils/timeformatter.cpp
1816 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitymenumodelpaths.cpp
1917 ${CMAKE_SOURCE_DIR}/plugins/Utils/windowkeysfilter.cpp
2018 ${CMAKE_SOURCE_DIR}/plugins/Utils/windowscreenshotprovider.cpp
tests/mocks/Utils/HomeKeyWatcher.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919QtObject {
2020 signal activated()
tests/mocks/Utils/Utils.qmltypes+31−28
@@ -4,9 +4,18 @@ import QtQuick.tooling 1.1
44// It is used for QML tooling purposes only.
55//
66// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Utils 0.1 plugins'
7+// 'qmlplugindump -notrelocatable Utils 0.1 tests/mocks'
88
99Module {
10+ Component {
11+ name: "Constants"
12+ prototype: "QObject"
13+ exports: ["Utils/Constants 0.1"]
14+ isCreatable: false
15+ isSingleton: true
16+ exportMetaObjectRevisions: [0]
17+ Property { name: "indicatorValueTimeout"; type: "int"; isReadonly: true }
18+ }
1019 Component {
1120 name: "EasingCurve"
1221 prototype: "QObject"
@@ -17,6 +26,22 @@ Module {
1726 Property { name: "progress"; type: "double" }
1827 Property { name: "value"; type: "double"; isReadonly: true }
1928 }
29+ Component {
30+ name: "InputWatcher"
31+ prototype: "QObject"
32+ exports: ["Utils/InputWatcher 0.1"]
33+ exportMetaObjectRevisions: [0]
34+ Property { name: "target"; type: "QObject"; isPointer: true }
35+ Property { name: "targetPressed"; type: "bool"; isReadonly: true }
36+ Signal {
37+ name: "targetChanged"
38+ Parameter { name: "value"; type: "QObject"; isPointer: true }
39+ }
40+ Signal {
41+ name: "targetPressedChanged"
42+ Parameter { name: "value"; type: "bool" }
43+ }
44+ }
2045 Component {
2146 name: "QAbstractProxyModel"
2247 prototype: "QAbstractItemModel"
@@ -59,33 +84,6 @@ Module {
5984 Method { name: "clear" }
6085 Method { name: "invalidate" }
6186 }
62− Component {
63− name: "RelativeTimeFormatter"
64− prototype: "TimeFormatter"
65− exports: ["Utils/RelativeTimeFormatter 0.1"]
66− exportMetaObjectRevisions: [0]
67− }
68− Component {
69− name: "TimeFormatter"
70− prototype: "QObject"
71− exports: ["Utils/GDateTimeFormatter 0.1", "Utils/TimeFormatter 0.1"]
72− exportMetaObjectRevisions: [0, 0]
73− Property { name: "format"; type: "string" }
74− Property { name: "timeString"; type: "string"; isReadonly: true }
75− Property { name: "time"; type: "qlonglong" }
76− Signal {
77− name: "formatChanged"
78− Parameter { name: "format"; type: "string" }
79− }
80− Signal {
81− name: "timeStringChanged"
82− Parameter { name: "timeString"; type: "string" }
83− }
84− Signal {
85− name: "timeChanged"
86− Parameter { name: "time"; type: "qlonglong" }
87− }
88− }
8987 Component {
9088 name: "UnityMenuModelPaths"
9189 prototype: "QObject"
@@ -160,6 +158,11 @@ Module {
160158 isCreatable: false
161159 isSingleton: true
162160 exportMetaObjectRevisions: [0]
161+ Property { name: "geometry"; type: "QVariantMap" }
162+ Signal {
163+ name: "geometryChanged"
164+ Parameter { name: "geometry"; type: "QVariantMap" }
165+ }
163166 Method {
164167 name: "saveGeometry"
165168 Parameter { name: "windowId"; type: "string" }
tests/mocks/Utils/plugin.cpp−13
@@ -23,14 +23,6 @@
2323
2424// local
2525#include "plugin.h"
26−#include "inputwatcher.h"
27−#include "qlimitproxymodelqml.h"
28−#include "unitysortfilterproxymodelqml.h"
29−#include "relativetimeformatter.h"
30−#include "timeformatter.h"
31−#include "unitymenumodelpaths.h"
32−#include "windowkeysfilter.h"
33−#include "easingcurve.h"
3426#include "windowstatestorage.h"
3527#include "constants.h"
3628
@@ -39,8 +31,6 @@
3931#include <inputwatcher.h>
4032#include <qlimitproxymodelqml.h>
4133#include <unitysortfilterproxymodelqml.h>
42−#include <relativetimeformatter.h>
43−#include <timeformatter.h>
4434#include <unitymenumodelpaths.h>
4535#include <windowkeysfilter.h>
4636#include <windowscreenshotprovider.h>
@@ -67,11 +57,8 @@ void FakeUtilsPlugin::registerTypes(const char *uri)
6757 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
6858 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
6959 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
70− qmlRegisterType<TimeFormatter>(uri, 0, 1, "TimeFormatter");
7160 qmlRegisterType<WindowKeysFilter>(uri, 0, 1, "WindowKeysFilter");
72− qmlRegisterType<GDateTimeFormatter>(uri, 0, 1, "GDateTimeFormatter");
7361 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
74− qmlRegisterType<RelativeTimeFormatter>(uri, 0, 1, "RelativeTimeFormatter");
7562 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
7663 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
7764 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
tests/mocks/Utils/windowstatestorage.cpp+17
@@ -44,3 +44,20 @@ QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defa
4444 if (!m_geometry.contains(windowId)) return defaultValue;
4545 return m_geometry.value(windowId).toRect();
4646}
47+
48+void WindowStateStorage::clear()
49+{
50+ m_state.clear();
51+ m_geometry.clear();
52+}
53+
54+void WindowStateStorage::saveState(const QString &windowId, WindowState state)
55+{
56+ m_state[windowId] = state;
57+}
58+
59+WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue)
60+{
61+ if (!m_state.contains(windowId)) return defaultValue;
62+ return m_state.value(windowId);
63+}
tests/mocks/Utils/windowstatestorage.h+12
@@ -22,12 +22,23 @@ class WindowStateStorage: public QObject
2222{
2323 Q_OBJECT
2424 Q_PROPERTY(QVariantMap geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
25+ Q_ENUMS(WindowState)
2526public:
27+ enum WindowState {
28+ WindowStateNormal,
29+ WindowStateMaximized
30+ };
2631 WindowStateStorage(QObject *parent = 0);
2732
33+ Q_INVOKABLE void saveState(const QString &windowId, WindowState state);
34+ Q_INVOKABLE WindowState getState(const QString &windowId, WindowState defaultValue);
35+
2836 Q_INVOKABLE void saveGeometry(const QString &windowId, const QRect &rect);
2937 Q_INVOKABLE QRect getGeometry(const QString &windowId, const QRect &defaultValue);
3038
39+ // Only in the mock, to easily restore a fresh state
40+ Q_INVOKABLE void clear();
41+
3142Q_SIGNALS:
3243 void geometryChanged(const QVariantMap& geometry);
3344
@@ -35,5 +46,6 @@ private:
3546 void setGeometry(const QVariantMap& geometry);
3647 QVariantMap geometry() const;
3748
49+ QHash<QString, WindowState> m_state;
3850 QVariantMap m_geometry;
3951};
tests/plugins/Dash/cardcreator/1.res+7−8
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -14,7 +14,6 @@ AbstractButton {
1414 implicitWidth: childrenRect.width;
1515 enabled: true;
1616
17−onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
1817readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
1918Item {
2019 id: artShapeHolder;
@@ -30,10 +29,9 @@ Item {
3029 sourceComponent: Item {
3130 id: artShape;
3231 objectName: "artShape";
33− property bool doShapeItem: components["art"]["conciergeMode"] !== true;
32+ readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
3433 visible: image.status == Image.Ready;
3534 readonly property alias image: artImage;
36− property alias borderSource: artShapeShape.borderSource;
3735 ShaderEffectSource {
3836 id: artShapeSource;
3937 sourceItem: artImage;
@@ -42,16 +40,17 @@ Item {
4240 height: 1;
4341 hideSource: doShapeItem;
4442 }
45− Shape {
43+ UbuntuShape {
4644 id: artShapeShape;
47− image: artShapeSource;
45+ source: artShapeSource;
4846 anchors.fill: parent;
4947 visible: doShapeItem;
5048 radius: "medium";
49+ aspect: root.artShapeStyle === "inset" ? UbuntuShape.Inset : UbuntuShape.Flat;
5150 }
5251 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
5352 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
54− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
53+ Component.onCompleted: { updateWidthHeightBindings(); }
5554 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
5655 function updateWidthHeightBindings() {
5756 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
@@ -87,7 +86,7 @@ Label {
8786 wrapMode: Text.Wrap;
8887 maximumLineCount: 2;
8988 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
90− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
89+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
9190 visible: showHeader ;
9291 width: undefined;
9392 text: root.title;
tests/plugins/Dash/cardcreator/2.res+9−8
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -23,11 +23,12 @@ Loader {
2323 sourceComponent: UbuntuShape {
2424 objectName: "background";
2525 radius: "medium";
26− color: getColor(0) || "white";
27− gradientColor: getColor(1) || color;
28− anchors.fill: parent;
29− image: backgroundImage.source ? backgroundImage : null;
30− property real luminance: Style.luminance(color);
26+ backgroundColor: getColor(0) || "white";
27+ secondaryBackgroundColor: getColor(1) || backgroundColor;
28+ backgroundMode: UbuntuShape.VerticalGradient;
29+ anchors.fill: parent;
30+ source: backgroundImage.source ? backgroundImage : null;
31+ property real luminance: Style.luminance(backgroundColor);
3132 property Image backgroundImage: Image {
3233 objectName: "backgroundImage";
3334 source: {
@@ -88,7 +89,7 @@ CroppedImageMinimumSourceSize {
8889 wrapMode: Text.Wrap;
8990 maximumLineCount: 2;
9091 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
91− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
92+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
9293 visible: showHeader ;
9394 width: undefined;
9495 text: root.title;
@@ -108,7 +109,7 @@ CroppedImageMinimumSourceSize {
108109 maximumLineCount: 1;
109110 fontSize: "x-small";
110111 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
111− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
112+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
112113 visible: titleLabel.visible && titleLabel.text;
113114 text: cardData && cardData["subtitle"] || "";
114115 font.weight: Font.Light;
tests/plugins/Dash/cardcreator/3.res+8−9
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -14,7 +14,6 @@ AbstractButton {
1414 implicitWidth: childrenRect.width;
1515 enabled: true;
1616
17−onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
1817readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
1918Item {
2019 id: artShapeHolder;
@@ -30,10 +29,9 @@ Item {
3029 sourceComponent: Item {
3130 id: artShape;
3231 objectName: "artShape";
33− property bool doShapeItem: components["art"]["conciergeMode"] !== true;
32+ readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
3433 visible: image.status == Image.Ready;
3534 readonly property alias image: artImage;
36− property alias borderSource: artShapeShape.borderSource;
3735 ShaderEffectSource {
3836 id: artShapeSource;
3937 sourceItem: artImage;
@@ -42,16 +40,17 @@ Item {
4240 height: 1;
4341 hideSource: doShapeItem;
4442 }
45− Shape {
43+ UbuntuShape {
4644 id: artShapeShape;
47− image: artShapeSource;
45+ source: artShapeSource;
4846 anchors.fill: parent;
4947 visible: doShapeItem;
5048 radius: "medium";
49+ aspect: root.artShapeStyle === "inset" ? UbuntuShape.Inset : UbuntuShape.Flat;
5150 }
5251 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
5352 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
54− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
53+ Component.onCompleted: { updateWidthHeightBindings(); }
5554 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
5655 function updateWidthHeightBindings() {
5756 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
@@ -87,7 +86,7 @@ Label {
8786 wrapMode: Text.Wrap;
8887 maximumLineCount: 2;
8988 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
90− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
89+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
9190 visible: showHeader ;
9291 width: undefined;
9392 text: root.title;
@@ -107,7 +106,7 @@ Label {
107106 maximumLineCount: 1;
108107 fontSize: "x-small";
109108 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
110− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
109+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
111110 visible: titleLabel.visible && titleLabel.text;
112111 text: cardData && cardData["subtitle"] || "";
113112 font.weight: Font.Light;
tests/plugins/Dash/cardcreator/4.res+3−3
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -72,7 +72,7 @@ Label {
7272 wrapMode: Text.Wrap;
7373 maximumLineCount: 2;
7474 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
75− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
75+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
7676 visible: showHeader ;
7777 width: undefined;
7878 text: root.title;
@@ -92,7 +92,7 @@ Label {
9292 maximumLineCount: 1;
9393 fontSize: "x-small";
9494 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
95− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
95+ color: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText;
9696 visible: titleLabel.visible && titleLabel.text;
9797 text: cardData && cardData["subtitle"] || "";
9898 font.weight: Font.Light;
tests/plugins/Dash/cardcreator/5.res+18−45
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -14,7 +14,6 @@ AbstractButton {
1414 implicitWidth: childrenRect.width;
1515 enabled: false;
1616
17−onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
1817readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
1918Item {
2019 id: artShapeHolder;
@@ -30,10 +29,9 @@ Item {
3029 sourceComponent: Item {
3130 id: artShape;
3231 objectName: "artShape";
33− property bool doShapeItem: components["art"]["conciergeMode"] !== true;
32+ readonly property bool doShapeItem: components["art"]["conciergeMode"] !== true;
3433 visible: image.status == Image.Ready;
3534 readonly property alias image: artImage;
36− property alias borderSource: artShapeShape.borderSource;
3735 ShaderEffectSource {
3836 id: artShapeSource;
3937 sourceItem: artImage;
@@ -42,16 +40,17 @@ Item {
4240 height: 1;
4341 hideSource: doShapeItem;
4442 }
45− Shape {
43+ UbuntuShape {
4644 id: artShapeShape;
47− image: artShapeSource;
45+ source: artShapeSource;
4846 anchors.fill: parent;
4947 visible: doShapeItem;
5048 radius: "medium";
49+ aspect: root.artShapeStyle === "inset" ? UbuntuShape.Inset : UbuntuShape.Flat;
5150 }
5251 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
5352 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
54− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
53+ Component.onCompleted: { updateWidthHeightBindings(); }
5554 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
5655 function updateWidthHeightBindings() {
5756 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
@@ -75,44 +74,18 @@ Item {
7574 }
7675Loader {
7776 id: overlayLoader;
78− anchors {
79− left: artShapeHolder.left;
80− right: artShapeHolder.right;
81− bottom: artShapeHolder.bottom;
82− }
83− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
77+ readonly property real overlayHeight: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
78+ anchors.fill: artShapeHolder;
79+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
8480 asynchronous: root.asynchronous;
8581 visible: showHeader && status == Loader.Ready;
86− sourceComponent: ShaderEffect {
82+ sourceComponent: UbuntuShapeOverlay {
8783 id: overlay;
88− height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
89− property real luminance: Style.luminance(overlayColor);
90− property color overlayColor: cardData && cardData["overlayColor"] || "#99000000";
91− property var source: ShaderEffectSource {
92− id: shaderSource;
93− sourceItem: artShapeLoader.item;
94− onVisibleChanged: if (visible) scheduleUpdate();
95− live: false;
96− sourceRect: Qt.rect(0, artShapeLoader.height - overlay.height, artShapeLoader.width, overlay.height);
97− }
98− vertexShader: "
99− uniform highp mat4 qt_Matrix;
100− attribute highp vec4 qt_Vertex;
101− attribute highp vec2 qt_MultiTexCoord0;
102− varying highp vec2 coord;
103− void main() {
104− coord = qt_MultiTexCoord0;
105− gl_Position = qt_Matrix * qt_Vertex;
106− }";
107− fragmentShader: "
108− varying highp vec2 coord;
109− uniform sampler2D source;
110− uniform lowp float qt_Opacity;
111− uniform highp vec4 overlayColor;
112− void main() {
113− lowp vec4 tex = texture2D(source, coord);
114− gl_FragColor = vec4(overlayColor.r, overlayColor.g, overlayColor.b, 1) * qt_Opacity * overlayColor.a * tex.a;
115− }";
84+ property real luminance: Style.luminance(overlayColor);
85+ aspect: UbuntuShape.Flat;
86+ radius: "medium";
87+ overlayColor: cardData && cardData["overlayColor"] || "#99000000";
88+ overlayRect: Qt.rect(0, 1 - overlayLoader.overlayHeight / height, 1, 1);
11689 }
11790 }
11891readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
@@ -124,14 +97,14 @@ Label {
12497 left: parent.left;
12598 leftMargin: units.gu(1);
12699 top: overlayLoader.top;
127− topMargin: units.gu(1);
100+ topMargin: units.gu(1) + overlayLoader.height - overlayLoader.overlayHeight;
128101 }
129102 elide: Text.ElideRight;
130103 fontSize: "small";
131104 wrapMode: Text.Wrap;
132105 maximumLineCount: 2;
133106 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
134− color: root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
107+ color: root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
135108 visible: showHeader && overlayLoader.active;
136109 width: undefined;
137110 text: root.title;
@@ -152,7 +125,7 @@ Label {
152125 maximumLineCount: 1;
153126 fontSize: "x-small";
154127 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
155− color: root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
128+ color: root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
156129 visible: titleLabel.visible && titleLabel.text;
157130 text: cardData && cardData["subtitle"] || "";
158131 font.weight: Font.Light;
tests/plugins/Dash/cardcreator/6.res+10−9
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -23,11 +23,12 @@ Loader {
2323 sourceComponent: UbuntuShape {
2424 objectName: "background";
2525 radius: "medium";
26− color: getColor(0) || "white";
27− gradientColor: getColor(1) || color;
28− anchors.fill: parent;
29− image: backgroundImage.source ? backgroundImage : null;
30− property real luminance: Style.luminance(color);
26+ backgroundColor: getColor(0) || "white";
27+ secondaryBackgroundColor: getColor(1) || backgroundColor;
28+ backgroundMode: UbuntuShape.VerticalGradient;
29+ anchors.fill: parent;
30+ source: backgroundImage.source ? backgroundImage : null;
31+ property real luminance: Style.luminance(backgroundColor);
3132 property Image backgroundImage: Image {
3233 objectName: "backgroundImage";
3334 source: {
@@ -67,7 +68,7 @@ Item {
6768 wrapMode: Text.Wrap;
6869 maximumLineCount: 2;
6970 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
70− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
71+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
7172 visible: showHeader ;
7273 width: undefined;
7374 text: root.title;
@@ -87,7 +88,7 @@ Item {
8788 maximumLineCount: 1;
8889 fontSize: "x-small";
8990 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
90− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
91+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
9192 visible: titleLabel.visible && titleLabel.text;
9293 text: cardData && cardData["subtitle"] || "";
9394 font.weight: Font.Light;
@@ -101,7 +102,7 @@ Item {
101102 rightMargin: units.gu(1);
102103 }
103104 source: cardData && cardData["emblem"] || "";
104− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
105+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
105106 height: source != "" ? titleLabel.font.pixelSize : 0;
106107 width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth;
107108 }
tests/plugins/Dash/cardcreator/7.res+10−9
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -23,11 +23,12 @@ Loader {
2323 sourceComponent: UbuntuShape {
2424 objectName: "background";
2525 radius: "medium";
26− color: getColor(0) || "white";
27− gradientColor: getColor(1) || color;
28− anchors.fill: parent;
29− image: backgroundImage.source ? backgroundImage : null;
30− property real luminance: Style.luminance(color);
26+ backgroundColor: getColor(0) || "white";
27+ secondaryBackgroundColor: getColor(1) || backgroundColor;
28+ backgroundMode: UbuntuShape.VerticalGradient;
29+ anchors.fill: parent;
30+ source: backgroundImage.source ? backgroundImage : null;
31+ property real luminance: Style.luminance(backgroundColor);
3132 property Image backgroundImage: Image {
3233 objectName: "backgroundImage";
3334 source: {
@@ -89,7 +90,7 @@ CroppedImageMinimumSourceSize {
8990 wrapMode: Text.Wrap;
9091 maximumLineCount: 2;
9192 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
92− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
93+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
9394 visible: showHeader ;
9495 width: undefined;
9596 text: root.title;
@@ -109,7 +110,7 @@ CroppedImageMinimumSourceSize {
109110 maximumLineCount: 1;
110111 fontSize: "x-small";
111112 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
112− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
113+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
113114 visible: titleLabel.visible && titleLabel.text;
114115 text: cardData && cardData["subtitle"] || "";
115116 font.weight: Font.Light;
@@ -122,7 +123,7 @@ CroppedImageMinimumSourceSize {
122123 rightMargin: units.gu(1);
123124 top: subtitleLabel.bottom;
124125 }
125− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
126+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
126127 fontScale: root.fontScale;
127128 model: cardData && cardData["attributes"];
128129 }
tests/plugins/Dash/cardcreator/8.res+7−6
@@ -2,7 +2,7 @@ AbstractButton {
22 id: root;
33 property var components;
44 property var cardData;
5− property var artShapeBorderSource: undefined;
5+ property string artShapeStyle: "inset";
66 property real fontScale: 1.0;
77 property var scopeStyle: null;
88 property int titleAlignment: Text.AlignLeft;
@@ -23,11 +23,12 @@ Loader {
2323 sourceComponent: UbuntuShape {
2424 objectName: "background";
2525 radius: "medium";
26− color: getColor(0) || "white";
27− gradientColor: getColor(1) || color;
26+ backgroundColor: getColor(0) || "white";
27+ secondaryBackgroundColor: getColor(1) || backgroundColor;
28+ backgroundMode: UbuntuShape.VerticalGradient;
2829 anchors.fill: parent;
29− image: backgroundImage.source ? backgroundImage : null;
30− property real luminance: Style.luminance(color);
30+ source: backgroundImage.source ? backgroundImage : null;
31+ property real luminance: Style.luminance(backgroundColor);
3132 property Image backgroundImage: Image {
3233 objectName: "backgroundImage";
3334 source: {
@@ -80,7 +81,7 @@ left: parent.left;
8081 wrapMode: Text.Wrap;
8182 maximumLineCount: 2;
8283 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
83− color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white");
84+ color: backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white");
8485 visible: showHeader ;
8586 width: parent.width - x;
8687 text: root.title;
tests/plugins/Dash/cardcreatortest.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import "../../../plugins/Dash/CardCreator.js" as CardCreator
1919
2020Item {
tests/plugins/Dash/horizontaljournaltest.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Item {
tests/plugins/Dash/horizontaljournaltry.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Item {
tests/plugins/Dash/listviewwithpageheadertest.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Rectangle {
tests/plugins/Dash/listviewwithpageheadertestsection.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Rectangle {
tests/plugins/Dash/listviewwithpageheadertestsectionexternalmodel.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Rectangle {
tests/plugins/Dash/organicgridtest.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Item {
tests/plugins/Dash/organicgridtry.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Item {
tests/plugins/Dash/tst_CardAttributes.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Dash 0.1
2020
tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import Dash 0.1
2121
2222Rectangle {
tests/plugins/Dash/tst_ListViewWithPageHeaderQML.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Dash 0.1
2020
tests/plugins/Dash/tst_ScopeStyle.qml+2−2
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Dash 0.1
20−import Ubuntu.Components 1.1
20+import Ubuntu.Components 1.3
2121import Utils 0.1
2222
2323Rectangle {
tests/plugins/Dash/verticaljournaltest.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Item {
tests/plugins/Dash/verticaljournaltry.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import Dash 0.1
1919
2020Item {
tests/plugins/IntegratedLightDM/greeter.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import IntegratedLightDM 0.1 as LightDM
1919
2020Item {
tests/plugins/ScreenGrabber/ScreenGrabberTest.cpp+11
@@ -55,6 +55,17 @@ private Q_SLOTS:
5555 QVERIFY(!args.first().toString().isEmpty());
5656 }
5757
58+ void testRotatedScreenshot()
59+ {
60+ QSignalSpy grabberSpy(m_grabber, &ScreenGrabber::screenshotSaved);
61+ m_grabber->captureAndSave(90); // rotate by 90°
62+ const QVariantList args = grabberSpy.takeFirst();
63+ const QString filename = args.first().toString();
64+ QVERIFY(!filename.isEmpty());
65+ QImage img(filename);
66+ QVERIFY(img.height() > img.width()); // verify that the image got rotated by 90° (height > width)
67+ }
68+
5869private:
5970 QQuickView *m_view;
6071 ScreenGrabber *m_grabber = nullptr;
tests/plugins/ScreenGrabber/grabber.qml+1−1
@@ -20,7 +20,7 @@ import ScreenGrabber 0.1
2020Rectangle {
2121 property var grabber: screenGrabber
2222
23− width: 100
23+ width: 101 // width intentionally bigger than height to test rotation
2424 height: 100
2525 color: "green"
2626
tests/plugins/Ubuntu/Gestures/DownwardsLauncher.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Gestures 0.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020
2121Item {
2222
tests/plugins/Ubuntu/Gestures/LeftwardsLauncher.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Gestures 0.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020
2121Item {
2222 id: root
tests/plugins/Ubuntu/Gestures/RightwardsLauncher.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Gestures 0.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020
2121Item {
2222 objectName: "rightwardsLauncher"
tests/plugins/Ubuntu/Gestures/UpwardsLauncher.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Gestures 0.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020
2121Item {
2222 id: root
tests/plugins/Ubuntu/Gestures/empty.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Gestures 0.1
1919
2020Item {
tests/plugins/Ubuntu/Gestures/touchGateExample.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import Ubuntu.Gestures 0.1
1919
2020Rectangle {
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Unity.Test 0.1
2020
2121Rectangle {
tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import Unity.Test 0.1
2121
tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020
2121/*
tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+1−5
@@ -19,9 +19,7 @@
1919#include <QQmlEngine>
2020#include <QQuickView>
2121#include <QSharedPointer>
22−#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
23− #include <private/qquickwindow_p.h>
24−#endif
22+#include <private/qquickwindow_p.h>
2523
2624// C++ std lib
2725#include <functional>
@@ -188,10 +186,8 @@ void tst_TouchGate::holdsEventsUntilGainsOwnership()
188186
189187 if (!ownershipAfterTouchEnd) {
190188 touchRegistry->removeCandidateOwnerForTouch(0, candidateItem);
191−#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
192189 QQuickWindowPrivate *wp = QQuickWindowPrivate::get(testItem->window());
193190 wp->flushDelayedTouchEvent();
194−#endif
195191 // TouchGate should now open its flood gates and let testItem get all
196192 // events from touch 0 produced so far
197193 QCOMPARE(testItem->touchEventsReceived.count(), 2);
tests/plugins/Unity/Indicators/UnityMenuModelStackTest.cpp+2−9
@@ -43,6 +43,8 @@ private Q_SLOTS:
4343 {
4444 delete m_model;
4545 m_model = nullptr;
46+ // send deleteLaters to avoid leaks.
47+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
4648 }
4749
4850 void testHeadOnSetHead()
@@ -146,19 +148,10 @@ private Q_SLOTS:
146148
147149 m_model->removeRow(removeIndex);
148150
149− waitFor([&stack, resultCount]() { return stack.count() == resultCount; }, 1000);
150151 QCOMPARE(stack.count(), resultCount);
151152 }
152153
153154private:
154− bool waitFor(std::function<bool()> functor, int ms) {
155−
156− QElapsedTimer timer;
157− timer.start();
158− while(!functor() && timer.elapsed() < ms) { QTest::qWait(10); }
159− return functor();
160− }
161−
162155 QVariant recuseAddMenu(int subMenuCount, int depth_remaining)
163156 {
164157 QVariantList rows;
tests/plugins/Unity/Launcher/launchermodeltest.cpp+1
@@ -57,6 +57,7 @@ public:
5757 QColor splashColorFooter() const override { return QColor(0,0,0,0); }
5858 Qt::ScreenOrientations supportedOrientations() const override { return Qt::PortraitOrientation; }
5959 bool rotatesWindowContents() const override { return false; }
60+ bool isTouchApp() const override { return true; }
6061
6162 // Methods used for mocking (not in the interface)
6263 void setFocused(bool focused) { m_focused = focused; Q_EMIT focusedChanged(focused); }
tests/plugins/Utils/CMakeLists.txt−1
@@ -7,7 +7,6 @@ include_directories(
77foreach(util_test
88 QLimitProxyModel
99 UnitySortFilterProxyModel
10− TimeFormatter
1110 HomeKeyWatcher
1211)
1312 add_executable(${util_test}TestExec ${util_test}Test.cpp ModelTest.cpp)
tests/plugins/Utils/TimeFormatterTest.cppdeleted−155
@@ -1,155 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU Lesser General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU Lesser General Public License for more details.
12− *
13− * You should have received a copy of the GNU Lesser General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Lars Uebernickel <lars.uebernickel@canonical.com>
17− */
18−
19−#include "timeformatter.h"
20−#include "relativetimeformatter.h"
21−
22−#include <locale.h>
23−
24−#include <QtTest>
25−#include <QDebug>
26−
27−class TimeFormatterTest : public QObject
28−{
29− Q_OBJECT
30−private:
31− void addTestData(QList<int> daysToAdd = QList<int>()) {
32− QTest::addColumn<QDateTime>("time");
33−
34− Q_FOREACH(int dayToAdd, daysToAdd) {
35− QDateTime time = QDateTime::currentDateTime().addDays(dayToAdd);
36− QDateTime am(time); am.setTime(QTime(1, 1, 1));
37− QDateTime midday(time); midday.setTime(QTime(12, 0, 0));
38− QDateTime pm(time); pm.setTime(QTime(17, 59, 59));
39−
40− QTest::newRow(QString("%1day-am").arg(dayToAdd).toLatin1()) << am;
41− QTest::newRow(QString("%1day-midday").arg(dayToAdd).toLatin1()) << midday;
42− QTest::newRow(QString("%1day-pm").arg(dayToAdd).toLatin1()) << pm;
43− }
44−
45− }
46−
47−private Q_SLOTS:
48− void testTimeFormatter_Format_data() { addTestData(QList<int>() << 0); }
49− void testTimeFormatter_Format()
50− {
51− QFETCH(QDateTime, time);
52− const QString format = "hh:mm dd.MM.yy";
53−
54− TimeFormatter formatter;
55− formatter.setTime(time.toMSecsSinceEpoch() * 1000);
56− formatter.setFormat(format);
57−
58− QCOMPARE(formatter.timeString(), time.toString(format));
59− }
60−
61− void tesGDatetTimeFormatter_Format_data() { addTestData(QList<int>() << 0); }
62− void tesGDatetTimeFormatter_Format()
63− {
64− QFETCH(QDateTime, time);
65− const QString format = "%d-%m-%Y %I:%M%p";
66−
67− GDateTimeFormatter formatter;
68− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
69− formatter.setFormat(format);
70−
71− QCOMPARE(formatter.timeString(), time.toString("dd-MM-yyyy hh:mmAP"));
72− }
73−
74− void tesRelativeTimeFormatter_FarBack_data() { addTestData(QList<int>() << -200 << -20 << -7); }
75− void tesRelativeTimeFormatter_FarBack()
76− {
77− QFETCH(QDateTime, time);
78−
79− RelativeTimeFormatter formatter;
80− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
81−
82− QCOMPARE(formatter.timeString(), time.toString("ddd dd MMM\u2003HH:mm"));
83− }
84−
85− void tesRelativeTimeFormatter_WeekBack_data() { addTestData(QList<int>() << -6 << -2); }
86− void tesRelativeTimeFormatter_WeekBack()
87− {
88− QFETCH(QDateTime, time);
89−
90− RelativeTimeFormatter formatter;
91− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
92−
93− QCOMPARE(formatter.timeString(), time.toString("ddd\u2003HH:mm"));
94− }
95−
96− void tesRelativeTimeFormatter_Yesterday_data() { addTestData(QList<int>() << -1); }
97− void tesRelativeTimeFormatter_Yesterday()
98− {
99− QFETCH(QDateTime, time);
100−
101− RelativeTimeFormatter formatter;
102− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
103−
104− QCOMPARE(formatter.timeString(), QString("Yesterday\u2003%1").arg(time.toString("HH:mm")));
105− }
106−
107− void tesRelativeTimeFormatter_Today_data() { addTestData(QList<int>() << 0); }
108− void tesRelativeTimeFormatter_Today()
109− {
110− QFETCH(QDateTime, time);
111−
112− RelativeTimeFormatter formatter;
113− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
114−
115− QCOMPARE(formatter.timeString(), time.toString("HH:mm"));
116− }
117−
118− void tesRelativeTimeFormatter_Tomorrow_data() { addTestData(QList<int>() << 1); }
119− void tesRelativeTimeFormatter_Tomorrow()
120− {
121− QFETCH(QDateTime, time);
122−
123− RelativeTimeFormatter formatter;
124− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
125−
126− QCOMPARE(formatter.timeString(), QString("Tomorrow\u2003%1").arg(time.toString("HH:mm")));
127− }
128−
129−
130− void tesRelativeTimeFormatter_WeekForward_data() { addTestData(QList<int>() << 2 << 6); }
131− void tesRelativeTimeFormatter_WeekForward()
132− {
133− QFETCH(QDateTime, time);
134−
135− RelativeTimeFormatter formatter;
136− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
137−
138− QCOMPARE(formatter.timeString(), time.toString("ddd\u2003HH:mm"));
139− }
140−
141− void tesRelativeTimeFormatter_FarForward_data() { addTestData(QList<int>() << 7 << 20 << 200); }
142− void tesRelativeTimeFormatter_FarForward()
143− {
144− QFETCH(QDateTime, time);
145−
146− RelativeTimeFormatter formatter;
147− formatter.setTime(time.toMSecsSinceEpoch() / 1000); // strftime in seconds since epoc
148−
149− QCOMPARE(formatter.timeString(), time.toString("ddd dd MMM\u2003HH:mm"));
150− }
151−};
152−
153−QTEST_GUILESS_MAIN(TimeFormatterTest)
154−
155−#include "TimeFormatterTest.moc"
tests/plugins/Utils/tst_UtilsStyle.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Utils 0.1
2020
tests/plugins/Wizard/tst_pagelist.cpp+5−5
@@ -88,13 +88,13 @@ void PageListTest::testIterate()
8888
8989 PageList pageList;
9090 QCOMPARE(pageList.index(), -1);
91− QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/1.qml");
91+ QCOMPARE(pageList.next(), QString(root.path() + "/a/" + PAGES_PATH + "/1.qml"));
9292 QCOMPARE(pageList.prev(), QString());
93− QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/2.qml");
94− QCOMPARE(pageList.prev(), root.path() + "/a/" + PAGES_PATH + "/1.qml");
93+ QCOMPARE(pageList.next(), QString(root.path() + "/a/" + PAGES_PATH + "/2.qml"));
94+ QCOMPARE(pageList.prev(), QString(root.path() + "/a/" + PAGES_PATH + "/1.qml"));
9595 QCOMPARE(pageList.index(), 0);
96− QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/2.qml");
97− QCOMPARE(pageList.next(), root.path() + "/a/" + PAGES_PATH + "/3.qml");
96+ QCOMPARE(pageList.next(), QString(root.path() + "/a/" + PAGES_PATH + "/2.qml"));
97+ QCOMPARE(pageList.next(), QString(root.path() + "/a/" + PAGES_PATH + "/3.qml"));
9898 QCOMPARE(pageList.index(), 2);
9999 QCOMPARE(pageList.next(), QString());
100100 QCOMPARE(pageList.index(), 2);
tests/qmltests/CMakeLists.txt+5−2
@@ -2,6 +2,7 @@
22add_subdirectory(Components)
33
44add_unity8_qmltest(. OrientedShell LIGHTDM)
5+add_unity8_qmltest(. DisabledScreenNotice)
56add_unity8_qmltest(. Shell LIGHTDM)
67add_unity8_qmltest(. ShellWithPin LIGHTDM)
78add_unity8_qmltest(Components Background)
@@ -15,6 +16,7 @@ add_unity8_qmltest(Components Rating)
1516add_unity8_qmltest(Components ResponsiveGridView)
1617add_unity8_qmltest(Components ResponsiveVerticalJournal)
1718add_unity8_qmltest(Components Showable)
19+add_unity8_qmltest(Components WallpaperResolver)
1820add_unity8_qmltest(Components ZoomableImage)
1921add_unity8_qmltest(Dash Dash)
2022add_unity8_qmltest(Dash DashContent)
@@ -24,7 +26,7 @@ add_unity8_qmltest(Dash CardCarousel)
2426add_unity8_qmlbenchmark(Dash CardBenchmark 1000)
2527add_unity8_qmltest(Dash CardTool)
2628add_unity8_qmltest(Dash GenericScopeView)
27−add_unity8_qmltest(Dash PageHeader)
29+add_unity8_qmltest(Dash DashPageHeader)
2830add_unity8_qmltest(Dash PreviewListView)
2931add_unity8_qmltest(Dash/Previews Preview)
3032add_unity8_qmltest(Dash/Previews PreviewActions)
@@ -40,6 +42,7 @@ add_unity8_qmltest(Dash/Previews PreviewProgress)
4042add_unity8_qmltest(Dash/Previews PreviewRatingDisplay)
4143add_unity8_qmltest(Dash/Previews PreviewRatingEdit)
4244add_unity8_qmltest(Dash/Previews PreviewRatingInput)
45+add_unity8_qmltest(Dash/Previews PreviewSharing)
4346add_unity8_qmltest(Dash/Previews PreviewTable)
4447add_unity8_qmltest(Dash/Previews PreviewTextSummary)
4548add_unity8_qmltest(Dash/Previews PreviewVideoPlayback)
@@ -78,7 +81,7 @@ add_unity8_qmltest(Stages SpreadDelegate)
7881add_unity8_qmltest(Stages SurfaceContainer)
7982add_unity8_qmltest(Stages SessionContainer)
8083add_unity8_qmltest(Stages TabletStage)
81−add_unity8_qmltest(Stages WindowMoveResizeArea)
84+add_unity8_qmltest(Stages WindowResizeArea)
8285add_unity8_qmltest(Stages Splash)
8386add_unity8_qmltest(Tutorial Tutorial LIGHTDM)
8487add_unity8_qmltest(Wizard Wizard ENVIRONMENT "OXIDE_NO_SANDBOX=1")
tests/qmltests/Components/tst_Background.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1
2020
tests/qmltests/Components/tst_Carousel.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Components/"
2020import "../../../qml/Components/carousel.js" as Carousel
tests/qmltests/Components/tst_Dialogs.qml+3−3
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.2
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import Unity.Test 0.1
2121
2222import "../../../qml/Components"
@@ -105,7 +105,7 @@ Rectangle {
105105 var dialogsPrivate = findInvisibleChild(dialogs, "dialogsPrivate");
106106 dialogsPrivate.showPowerDialog();
107107 var dialogLoader = findInvisibleChild(dialogs, "dialogLoader");
108− tryCompare(dialogLoader.item, "focus", true);
108+ tryCompare(dialogLoader.item.__foreground, "focus", true);
109109 }
110110 }
111111}
tests/qmltests/Components/tst_DragHandle.qml+2−2
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "../../../qml/Components"
1919import "tst_DragHandle"
20−import Ubuntu.Components 0.1
20+import Ubuntu.Components 1.3
2121import Ubuntu.Gestures 0.1
2222import Unity.Test 0.1
2323
tests/qmltests/Components/tst_DragHandle/BidirectionalShowable.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "../../../../qml/Components"
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Ubuntu.Gestures 0.1
2121
2222Item {
tests/qmltests/Components/tst_DragHandle/HorizontalShowable.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "../../../../qml/Components"
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Ubuntu.Gestures 0.1
2121
2222Showable {
tests/qmltests/Components/tst_DragHandle/VerticalShowable.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "../../../../qml/Components"
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Ubuntu.Gestures 0.1
2121
2222Showable {
tests/qmltests/Components/tst_DraggingArea.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Components"
2020
tests/qmltests/Components/tst_EdgeDragEvaluator.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import "../../../qml/Components"
1919
2020Item {
tests/qmltests/Components/tst_LazyImage.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Components"
20−import Ubuntu.Components 0.1
20+import Ubuntu.Components 1.3
2121import Unity.Test 0.1 as UT
2222import "tst_LazyImage"
2323
@@ -32,7 +32,7 @@ Rectangle {
3232 rightMargin: 2 * parent.width / 3
3333 }
3434
35− color: Theme.palette.normal.baseText
35+ color: theme.palette.normal.baseText
3636
3737 Column {
3838 anchors { fill: parent; margins: units.gu(5) }
tests/qmltests/Components/tst_LazyImage/ImageControls.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../../../../qml/Components"
2020
2121Row {
tests/qmltests/Components/tst_Lockscreen.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Components"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Test 0.1 as UT
2323
2424Rectangle {
tests/qmltests/Components/tst_PhysicalKeysMapper.qml+11−10
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Components"
2020import Powerd 0.1
@@ -67,26 +67,27 @@ TestCase {
6767 Powerd.setStatus(data.status, Powerd.Unknown);
6868 physicalKeysMapper.powerKeyLongPressTime = 500;
6969
70− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: false });
70+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: false }, 100);
7171
7272 // After the first key press the screen is always on
7373 // and the rest of keypresses are auto repeat
7474 Powerd.setStatus(Powerd.On, Powerd.Unknown);
7575
76− for (var i = 0; i < 3; ++i) {
77− wait(10);
78− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true});
79− }
76+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 300);
77+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 400);
78+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 500);
79+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 599);
8080
8181 // powerKeyLongPressed should not have been emitted yet.
8282 compare(powerSpy.count, 0);
8383
84− for (var i = 0; i < 10; ++i) {
85− wait(50);
86− physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true});
87− }
84+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 600);
8885
8986 compare(powerSpy.count, 1);
87+
88+ // Confirm we only emit once
89+ physicalKeysMapper.onKeyPressed({ key: Qt.Key_PowerDown, isAutoRepeat: true}, 601);
90+ compare(powerSpy.count, 1);
9091 }
9192
9293 function test_screenshotButtons_data() {
tests/qmltests/Components/tst_Rating.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,17 +14,17 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Components"
20−import Ubuntu.Components 0.1
20+import Ubuntu.Components 1.3
2121import Unity.Test 0.1 as UT
2222
2323Rectangle {
2424 id: root
2525 width: units.gu(40)
2626 height: units.gu(10)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 Rating {
3030 id: rating
tests/qmltests/Components/tst_ResponsiveGridView.qml+3−3
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Components"
21−import Ubuntu.Components.ListItems 0.1 as ListItem
22−import Ubuntu.Components 0.1
21+import Ubuntu.Components.ListItems 1.3 as ListItem
22+import Ubuntu.Components 1.3
2323import Unity.Test 0.1 as UT
2424
2525Item {
tests/qmltests/Components/tst_ResponsiveVerticalJournal.qml+3−3
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Components"
21−import Ubuntu.Components.ListItems 0.1 as ListItem
22−import Ubuntu.Components 0.1
21+import Ubuntu.Components.ListItems 1.3 as ListItem
22+import Ubuntu.Components 1.3
2323import Utils 0.1
2424import Unity.Test 0.1 as UT
2525
tests/qmltests/Components/tst_Showable.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Unity.Test 0.1 as UT
2121import ".."
2222import "../../../qml/Components"
tests/qmltests/Components/tst_WallpaperResolver.qmlnew file+89
@@ -0,0 +1,89 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtTest 1.0
19+import Ubuntu.Components 1.3
20+import Unity.Test 0.1
21+import AccountsService 0.1
22+import GSettings 1.0
23+
24+import "../../../qml/Components"
25+
26+
27+Image {
28+ width: units.gu(70)
29+ height: units.gu(70)
30+
31+ source: wallpaperResolver.background
32+
33+ WallpaperResolver {
34+ id: wallpaperResolver
35+ width: units.gu(70)
36+ }
37+
38+ UnityTestCase {
39+ id: testCase
40+ name: "WallpaperResolver"
41+ when: windowShown
42+
43+ function test_background_data() {
44+ return [
45+ {tag: "color",
46+ accounts: Qt.resolvedUrl("data:image/svg+xml,<svg><rect width='100%' height='100%' fill='#dd4814'/></svg>"),
47+ gsettings: "",
48+ output: Qt.resolvedUrl("data:image/svg+xml,<svg><rect width='100%' height='100%' fill='#dd4814'/></svg>")},
49+
50+ {tag: "empty", accounts: "", gsettings: "", output: "defaultBackground"},
51+
52+ {tag: "as-specified",
53+ accounts: Qt.resolvedUrl("../../data/unity/backgrounds/blue.png"),
54+ gsettings: "",
55+ output: Qt.resolvedUrl("../../data/unity/backgrounds/blue.png")},
56+
57+ {tag: "gs-specified",
58+ accounts: "",
59+ gsettings: Qt.resolvedUrl("../../data/unity/backgrounds/red.png"),
60+ output: Qt.resolvedUrl("../../data/unity/backgrounds/red.png")},
61+
62+ {tag: "both-specified",
63+ accounts: Qt.resolvedUrl("../../data/unity/backgrounds/blue.png"),
64+ gsettings: Qt.resolvedUrl("../../data/unity/backgrounds/red.png"),
65+ output: Qt.resolvedUrl("../../data/unity/backgrounds/blue.png")},
66+
67+ {tag: "invalid-as",
68+ accounts: Qt.resolvedUrl("../../data/unity/backgrounds/nope.png"),
69+ gsettings: Qt.resolvedUrl("../../data/unity/backgrounds/red.png"),
70+ output: Qt.resolvedUrl("../../data/unity/backgrounds/red.png")},
71+
72+ {tag: "invalid-both",
73+ accounts: Qt.resolvedUrl("../../data/unity/backgrounds/nope.png"),
74+ gsettings: Qt.resolvedUrl("../../data/unity/backgrounds/stillnope.png"),
75+ output: "defaultBackground"},
76+ ]
77+ }
78+ function test_background(data) {
79+ AccountsService.backgroundFile = data.accounts;
80+ GSettingsController.setPictureUri(data.gsettings);
81+
82+ if (data.output === "defaultBackground") {
83+ tryCompare(wallpaperResolver, "background", wallpaperResolver.defaultBackground);
84+ } else {
85+ tryCompare(wallpaperResolver, "background", data.output);
86+ }
87+ }
88+ }
89+}
tests/qmltests/Components/tst_ZoomableImage.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Components"
2020import Unity.Test 0.1 as UT
tests/qmltests/Dash/Previews/MockPreviewWidget.qml+1−1
@@ -15,7 +15,7 @@
1515 *
1616 */
1717
18−import QtQuick 2.0
18+import QtQuick 2.4
1919import "../../../../qml/Dash/Previews"
2020
2121PreviewWidget {
tests/qmltests/Dash/Previews/tst_Preview.qml+3−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
@@ -24,7 +24,7 @@ Rectangle {
2424 id: root
2525 width: units.gu(60)
2626 height: units.gu(60)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 Item {
3030 id: shell
tests/qmltests/Dash/Previews/tst_PreviewActions.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222
2323
2424Rectangle {
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222import QtMultimedia 5.0
@@ -25,7 +25,7 @@ Rectangle {
2525 id: root
2626 width: units.gu(60)
2727 height: units.gu(80)
28− color: Theme.palette.selected.background
28+ color: theme.palette.selected.background
2929
3030 property var tracksModel0: {
3131 "tracks": [ ]
tests/qmltests/Dash/Previews/tst_PreviewComment.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
tests/qmltests/Dash/Previews/tst_PreviewCommentInput.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
tests/qmltests/Dash/Previews/tst_PreviewExpandable.qml+6−6
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
@@ -24,7 +24,7 @@ Rectangle {
2424 id: root
2525 width: units.gu(40)
2626 height: units.gu(80)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 property string longText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh.\nLorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh."
3030 property string longText2: "This is a very very very long text. 1 This is a very very very long text. 2 This is a very very very long text. 3 This is a very very very long text. 4 This is a very very very long text. 5 This is a very very very long text. 6 This is a very very very long text. 7 This is a very very very long text. 8 This is a very very very long text. 9 This is a very very very long text. 10 This is a very very very long text. 11 This is a very very very long text."
@@ -319,9 +319,9 @@ Rectangle {
319319 previewWidgetFactory.widgetType = allWidgetsModel.get(i).type;
320320 previewWidgetFactory.active = true;
321321
322− // Wait for the height ot settle by waiting twice the time of the
322+ // Wait for the height ot settle by waiting four times the time of the
323323 // longest of the height behaviour animations
324− wait(UbuntuAnimation.SnapDuration * 2);
324+ wait(UbuntuAnimation.SnapDuration * 4);
325325
326326 // Check the item inside the expandable has the same height
327327 // as the one straight from the factory
tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+2−2
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
@@ -149,7 +149,7 @@ Rectangle {
149149 tryCompareFunction(function() { return findChild(previewHeader, "mascotShape") != null }, true);
150150 var mascot = findChild(previewHeader, "mascotShape");
151151 tryCompare(mascot, "visible", true);
152− tryCompare(mascot.image, "status", Image.Ready);
152+ tryCompare(mascot.source, "status", Image.Ready);
153153 }
154154 }
155155}
tests/qmltests/Dash/Previews/tst_PreviewIconActions.qml+3−3
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222
2323
2424Rectangle {
@@ -104,7 +104,7 @@ Rectangle {
104104
105105 var button = findChild(root, "button" + buttonId);
106106 var image = findChildsByType(button, "QQuickImage")[0];
107− var label = findChildsByType(button, "Label")[0];
107+ var label = findChildsByType(button, "UCLabel")[0];
108108
109109 compare(image.source, buttonIcon);
110110 compare(label.text, buttonLabel);
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
tests/qmltests/Dash/Previews/tst_PreviewPayments.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222
2323Rectangle {
2424 id: root
tests/qmltests/Dash/Previews/tst_PreviewProgress.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222
2323Rectangle {
2424 id: root
tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
@@ -24,7 +24,7 @@ Rectangle {
2424 id: root
2525 width: units.gu(40)
2626 height: units.gu(80)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 property var reviewsModel0: {
3030 "reviews": [ ]
tests/qmltests/Dash/Previews/tst_PreviewRatingEdit.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
@@ -24,7 +24,7 @@ Rectangle {
2424 id: root
2525 width: units.gu(40)
2626 height: units.gu(80)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 property var widgetData0: { "visible": "both", "required": "both", author: "Some dude", rating: 4.5, review: "Very cool app" }
3030
tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
@@ -24,7 +24,7 @@ Rectangle {
2424 id: root
2525 width: units.gu(40)
2626 height: units.gu(80)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 property real validInputRating: 1
3030 property real invalidInputRating: -1
tests/qmltests/Dash/Previews/tst_PreviewSharing.qmlnew file+71
@@ -0,0 +1,71 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtTest 1.0
19+import Ubuntu.Components 1.3
20+import "../../../../qml/Dash/Previews"
21+import Unity.Test 0.1 as UT
22+
23+Rectangle {
24+ id: root
25+ width: units.gu(40)
26+ height: units.gu(80)
27+ color: "black"
28+
29+ property var shareData: {
30+ "uri": [
31+ "Text here",
32+ "text here 2",
33+ "text here 3"
34+ ],
35+ "contentType": "text"
36+ }
37+
38+ property var shareDataNoUri: {
39+ "uri": "",
40+ "contentType": "text"
41+ }
42+
43+ PreviewSharing {
44+ id: previewSharing
45+ anchors { left: parent.left; bottom: parent.bottom; }
46+ shareData: root.shareData
47+ }
48+
49+ UT.UnityTestCase {
50+ name: "PreviewSharingTest"
51+ when: windowShown
52+
53+ property Item peerPicker: findChild(previewSharing.rootItem, "peerPicker")
54+
55+ function cleanup() {
56+ peerPicker.visible = false;
57+ previewSharing.shareData = root.shareData;
58+ }
59+
60+ function test_visible() {
61+ compare(previewSharing.visible, true);
62+ previewSharing.shareData = shareDataNoUri;
63+ compare(previewSharing.visible, false);
64+ }
65+
66+ function test_open_picker() {
67+ mouseClick(previewSharing);
68+ compare(peerPicker.visible, true);
69+ }
70+ }
71+}
tests/qmltests/Dash/Previews/tst_PreviewTable.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
@@ -24,7 +24,7 @@ Rectangle {
2424 id: root
2525 width: units.gu(40)
2626 height: units.gu(80)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 property var widgetDataComplete: {
3030 "title": "Title here longa long long long long long long long long long long",
tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+4−4
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import "../../../../qml/Dash/Previews"
2121import Unity.Test 0.1 as UT
2222
@@ -24,7 +24,7 @@ Rectangle {
2424 id: root
2525 width: units.gu(40)
2626 height: units.gu(80)
27− color: Theme.palette.selected.background
27+ color: theme.palette.selected.background
2828
2929 property var widgetDataComplete: {
3030 "title": "Title here",
tests/qmltests/Dash/Previews/tst_PreviewVideoPlayback.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+3−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
@@ -23,7 +23,7 @@ Rectangle {
2323 id: root
2424 width: units.gu(60)
2525 height: units.gu(80)
26− color: Theme.palette.selected.background
26+ color: theme.palette.selected.background
2727
2828 PreviewWidgetFactory {
2929 id: factory
tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+2−2
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../../qml/Dash/Previews"
2020import Unity.Test 0.1 as UT
@@ -41,7 +41,7 @@ Rectangle {
4141
4242 Loader {
4343 id: loader
44− anchors.centerIn: parent
44+ width: parent.width
4545 sourceComponent: PreviewZoomableImage {
4646 widgetData: widgetData0
4747 }
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import QtTest 1.0
2020import "../../../../qml/Dash/ScopeSettings"
2121import Unity.Test 0.1 as UT
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingList.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import QtTest 1.0
2020import "../../../../qml/Dash/ScopeSettings"
2121import Unity.Test 0.1 as UT
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import QtTest 1.0
2020import "../../../../qml/Dash/ScopeSettings"
2121import Unity.Test 0.1 as UT
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import QtTest 1.0
2020import "../../../../qml/Dash/ScopeSettings"
2121import Unity.Test 0.1 as UT
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingsWidgetFactory.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import QtTest 1.0
2020import "../../../../qml/Dash/ScopeSettings"
2121import Unity.Test 0.1 as UT
tests/qmltests/Dash/tst_Card.qml+7−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Unity.Test 0.1 as UT
2121import "../../../qml/Dash"
2222import "CardHelpers.js" as Helpers
@@ -443,11 +443,11 @@ Rectangle {
443443 }
444444
445445 if (data.hasOwnProperty("color")) {
446− tryCompare(background, "color", data.color);
446+ tryCompare(background, "backgroundColor", data.color);
447447 }
448448
449449 if (data.hasOwnProperty("gradientColor")) {
450− tryCompare(background, "gradientColor", data.gradientColor);
450+ tryCompare(background, "secondaryBackgroundColor", data.gradientColor);
451451 }
452452
453453 if (data.hasOwnProperty("image")) {
@@ -520,9 +520,9 @@ Rectangle {
520520 waitForRendering(selector);
521521 waitForRendering(card);
522522
523− background.color = data.tag;
523+ background.backgroundColor = data.tag;
524524
525− var fontColor = data.dark ? Theme.palette.normal.baseText : "white";
525+ var fontColor = data.dark ? theme.palette.normal.baseText : "white";
526526
527527 tryCompareFunction(function() { return Qt.colorEqual(summary.color, fontColor); }, true);
528528 tryCompareFunction(function() { return Qt.colorEqual(title.color, fontColor); }, true);
tests/qmltests/Dash/tst_CardBenchmark.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Unity.Test 0.1 as UT
2121import "../../../qml/Dash"
2222import "CardHelpers.js" as Helpers
tests/qmltests/Dash/tst_CardTool.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Unity.Test 0.1 as UT
2121import "../../../qml/Dash"
2222import "CardHelpers.js" as Helpers
tests/qmltests/Dash/tst_Dash.qml+3−3
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Dash"
20−import Ubuntu.Components 0.1
20+import Ubuntu.Components 1.3
2121import Unity.Test 0.1 as UT
2222
2323Item {
@@ -319,7 +319,7 @@ Item {
319319
320320 // Click on the store
321321 var scopesListPageHeader = findChild(scopesList, "pageHeader");
322− var searchButton = findChild(scopesListPageHeader, "store_header_button");
322+ var searchButton = findChild(scopesListPageHeader, "store_action_button");
323323 mouseClick(searchButton);
324324
325325 spy.wait();
tests/qmltests/Dash/tst_DashContent.qml+6−6
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import "../../../qml/Dash"
2020import "../../../qml/Components"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity 0.2
2323import Unity.Test 0.1 as UT
2424import Utils 0.1
@@ -215,7 +215,7 @@ Item {
215215 verify(pageHeader, "Could not find the scope page header.");
216216 var innerHeader = findChild(pageHeader, "innerPageHeader");
217217 verify(innerHeader, "Could not find the scope page header.");
218− compare(innerHeader.title, scopesModel.getScope(data.index).name);
218+ compare(innerHeader.config.title, scopesModel.getScope(data.index).name);
219219 }
220220
221221 function test_is_active_data() {
@@ -552,13 +552,13 @@ Item {
552552 }
553553
554554 function getSettledButtons() {
555− var buttons = findChildsByType(dashContent, "AbstractButton");
555+ var buttons = findChildsByType(dashContent, "UCAbstractButton");
556556 wait(2500);
557− var aux = findChildsByType(dashContent, "AbstractButton");
557+ var aux = findChildsByType(dashContent, "UCAbstractButton");
558558 while (!compareArrays(aux, buttons)) {
559559 buttons = aux;
560560 wait(2500);
561− aux = findChildsByType(dashContent, "AbstractButton");
561+ aux = findChildsByType(dashContent, "UCAbstractButton");
562562 }
563563 return buttons;
564564 }
tests/qmltests/Dash/tst_PageHeader.qml → tests/qmltests/Dash/tst_DashPageHeader.qmlrenamed+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Dash"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity 0.2
2323import Unity.Test 0.1 as UT
2424
@@ -244,7 +244,7 @@ Item {
244244 anchors.fill: parent
245245 spacing: units.gu(1)
246246
247− PageHeader {
247+ DashPageHeader {
248248 id: pageHeader
249249 anchors {
250250 left: parent.left
@@ -254,7 +254,7 @@ Item {
254254 searchEntryEnabled: true
255255 title: "%^$%^%^&%^&%^$%GHR%"
256256 scopeStyle: QtObject {
257− readonly property color foreground: Theme.palette.normal.baseText
257+ readonly property color foreground: theme.palette.normal.baseText
258258 readonly property url headerLogo: showImageCheckBox.checked ? pageHeader.titleImageSource : ""
259259 }
260260 showBackButton: showBackButtonCheckBox.checked
tests/qmltests/Dash/tst_GenericScopeView.qml+5−5
@@ -14,13 +14,13 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity 0.2
2020import ".."
2121import "../../../qml/Dash"
2222import "../../../qml/Components"
23−import Ubuntu.Components 1.1
23+import Ubuntu.Components 1.3
2424import Unity.Test 0.1 as UT
2525
2626Item {
@@ -429,7 +429,7 @@ Item {
429429 // open
430430 tryCompare(testCase.subPageLoader, "open", false);
431431 tryCompare(testCase.subPageLoader, "visible", false);
432− var settings = findChild(innerHeader, "settings_header_button");
432+ var settings = findChild(innerHeader, "settings_action_button");
433433 mouseClick(settings);
434434 tryCompare(testCase.subPageLoader, "open", true);
435435 tryCompareFunction(function() { return (String(subPageLoader.source)).indexOf("ScopeSettingsPage.qml") != -1; }, true);
@@ -500,7 +500,7 @@ Item {
500500 mouseClick(seeAll0);
501501 verify(category0.expanded);
502502 tryCompare(category0, "height", category0.item.expandedHeight + seeAll0.height);
503− tryCompare(genericScopeView.categoryView, "contentY", units.gu(14));
503+ tryCompare(genericScopeView.categoryView, "contentY", units.gu(13));
504504
505505 scrollToEnd();
506506
@@ -577,7 +577,7 @@ Item {
577577 verify(innerHeader, "Could not find the inner header");
578578
579579 expectFail("Apps", "Click scope should not have a favorite button");
580− var favoriteAction = findChild(innerHeader, "favorite_header_button");
580+ var favoriteAction = findChild(innerHeader, "favorite_action_button");
581581 verify(favoriteAction, "Could not find the favorite action.");
582582 mouseClick(favoriteAction);
583583
tests/qmltests/Dash/tst_PreviewListView.qml+5−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014 Canonical Ltd.
2+ * Copyright 2014,2015 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import "../../../qml/Dash"
2121import Unity.Test 0.1 as UT
2222import Unity 0.2 as Unity
@@ -26,7 +26,7 @@ Rectangle {
2626 id: root
2727 width: units.gu(60)
2828 height: units.gu(60)
29− color: Theme.palette.selected.background
29+ color: theme.palette.selected.background
3030
3131 Unity.MockScope {
3232 id: mockScope
@@ -91,7 +91,7 @@ Rectangle {
9191 var header = findChild(listView, "innerPageHeader");
9292 verify(header, "Could not find the preview header");
9393
94− compare(header.title, "Mock Scope");
94+ compare(header.config.title, "Mock Scope");
9595 }
9696
9797 function test_header_style() {
tests/qmltests/Greeter/TestView.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
18−import Ubuntu.Components 1.1
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import "../Components"
2020
2121Item {
tests/qmltests/Greeter/tst_Clock.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Greeter"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Indicators 0.1 as Indicators
2323import Unity.Test 0.1 as UT
2424
tests/qmltests/Greeter/tst_Greeter.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Greeter"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import AccountsService 0.1
2323import GSettings 1.0
2424import IntegratedLightDM 0.1 as LightDM
tests/qmltests/Greeter/tst_Infographics.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Greeter"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Test 0.1 as UT
2323import IntegratedLightDM 0.1 as LightDM
2424
tests/qmltests/Greeter/tst_NarrowView.qml+2−2
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Greeter"
2121import IntegratedLightDM 0.1 as LightDM
22−import Ubuntu.Components 0.1
22+import Ubuntu.Components 1.3
2323import Unity.Test 0.1 as UT
2424
2525Item {
tests/qmltests/Greeter/tst_WideView.qml+2−2
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Greeter"
2121import IntegratedLightDM 0.1 as LightDM
22−import Ubuntu.Components 0.1
22+import Ubuntu.Components 1.3
2323import Unity.Test 0.1 as UT
2424
2525Item {
tests/qmltests/Launcher/tst_Launcher.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import Unity.Test 0.1
21−import Ubuntu.Components 1.1
21+import Ubuntu.Components 1.3
2222import ".."
2323import "../../../qml/Launcher"
2424import Unity.Launcher 0.1
tests/qmltests/Notifications/tst_Notifications.qml+1−1
@@ -20,7 +20,7 @@ import QtTest 1.0
2020import ".."
2121import "../../../qml/Notifications"
2222import "../../../qml/Components/UnityInputInfo"
23−import Ubuntu.Components 1.2
23+import Ubuntu.Components 1.3
2424import Unity.Test 0.1
2525import Unity.Notifications 1.0
2626import QtMultimedia 5.0
tests/qmltests/Notifications/tst_OptionToggle.qml+2−3
@@ -17,14 +17,13 @@
1717 * Mirco Mueller <mirco.mueller@canonical.com>
1818 */
1919
20−import QtQuick 2.0
20+import QtQuick 2.4
2121import QtTest 1.0
2222import ".."
2323import "../../../qml/Notifications"
24−import Ubuntu.Components 0.1
24+import Ubuntu.Components 1.3
2525import Unity.Test 0.1
2626import Unity.Notifications 1.0
27−import QtMultimedia 5.0
2827
2928Row {
3029 id: rootRow
tests/qmltests/Notifications/tst_SwipeToAct.qml+1−1
@@ -20,7 +20,7 @@ import QtTest 1.0
2020import ".."
2121import "../../../qml/Notifications"
2222import "../../../qml/Components/UnityInputInfo"
23−import Ubuntu.Components 0.1
23+import Ubuntu.Components 1.3
2424import Unity.Test 0.1
2525import Unity.Notifications 1.0
2626
tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import ".."
2020import "../../../qml/Notifications"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Test 0.1
2323import Unity.Notifications 1.0
2424
tests/qmltests/Panel/IndicatorTest.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import "../../../qml/Panel"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Test 0.1 as UT
2323import Unity.Indicators 0.1 as Indicators
2424
tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import Unity.Test 0.1 as UT
2020import Unity.Indicators 0.1 as Indicators
21−import Ubuntu.Components 1.1
21+import Ubuntu.Components 1.3
2222import Powerd 0.1
2323import Lights 0.1
2424import QMenuModel 0.1
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+7−17
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import Ubuntu.Settings.Menus 0.1 as Menus
@@ -50,10 +50,6 @@ Item {
5050 }
5151 }
5252
53− Utils.GDateTimeFormatter {
54− id: timeFormatter
55− }
56−
5753 UT.UnityTestCase {
5854 name: "MenuItemFactory"
5955 when: windowShown
@@ -374,9 +370,9 @@ Item {
374370 function test_create_alarmMenu_data() {
375371 return [
376372 {label: "testLabel1", enabled: true, icon: "file:///testIcon1", color: Qt.rgba(0, 0, 0, 0),
377− time: new Date(2014, 04, 14), timeFormat: "%a %d %b %l:%M %p"},
373+ time: new Date(2014, 04, 14)},
378374 {label: "testLabel2", enabled: false, icon: "file:///testIcon2", color: Qt.rgba(1, 0, 0, 0),
379− time: new Date(2015, 11, 31), timeFormat: "%A" },
375+ time: new Date(2015, 11, 31) },
380376 ];
381377 }
382378
@@ -386,11 +382,8 @@ Item {
386382 menuData.sensitive = data.enabled;
387383 menuData.icon = data.icon;
388384 menuData.ext = {
389− 'xCanonicalTime': data.time.getTime() / 1000,
390− 'xCanonicalTimeFormat': data.timeFormat
385+ 'xCanonicalTime': data.time.getTime() / 1000 // expected in seconds
391386 };
392− timeFormatter.format = data.timeFormat;
393− timeFormatter.time = data.time.getTime() / 1000;
394387
395388 loader.data = menuData;
396389 loader.sourceComponent = factory.load(menuData);
@@ -399,7 +392,7 @@ Item {
399392
400393 compare(loader.item.text, data.label, "Label does not match data");
401394 compare(loader.item.iconSource, data.icon, "Icon does not match data");
402− compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
395+ compare(loader.item.time, i18n.relativeDateTime(data.time), "Time does not match data");
403396 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
404397 }
405398
@@ -419,11 +412,8 @@ Item {
419412 menuData.icon = data.icon;
420413 menuData.ext = {
421414 'xCanonicalColor': data.colour,
422− 'xCanonicalTime': data.time.getTime() / 1000,
423− 'xCanonicalTimeFormat': data.timeFormat
415+ 'xCanonicalTime': data.time.getTime() / 1000 // expected in seconds
424416 };
425− timeFormatter.format = data.timeFormat;
426− timeFormatter.time = data.time.getTime() / 1000;
427417
428418 loader.data = menuData;
429419 loader.sourceComponent = factory.load(menuData);
@@ -432,7 +422,7 @@ Item {
432422
433423 compare(loader.item.text, data.label, "Label does not match data");
434424 compare(loader.item.iconSource, data.icon, "Icon does not match data");
435− compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
425+ compare(loader.item.time, i18n.relativeDateTime(data.time), "Time does not match data");
436426 compare(loader.item.eventColor, data.color, "Colour does not match data");
437427 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
438428 }
tests/qmltests/Panel/Indicators/tst_MessageMenuItemFactory.qml+7−14
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import QMenuModel 0.1
@@ -32,10 +32,6 @@ Item {
3232 menuIndex: 0
3333 }
3434
35− Utils.RelativeTimeFormatter {
36− id: timeFormatter
37− }
38−
3935 UT.UnityTestCase {
4036 name: "MessageMenuItemFactory"
4137 when: windowShown
@@ -82,17 +78,16 @@ Item {
8278 menuData.label = data.title;
8379 menuData.sensitive = data.enabled;
8480 menuData.ext = {
85− 'xCanonicalTime': data.time.getTime()*1000,
81+ 'xCanonicalTime': data.time.getTime()*1000, // expected in microseconds
8682 'xCanonicalText': data.body,
8783 'icon': data.avatar,
8884 'xCanonicalAppIcon': data.icon,
8985 };
9086 factory.menuData = menuData;
91− timeFormatter.time = data.time.getTime()/1000;
9287
9388 tryCompare(factory.item, "objectName", "simpleTextMessage");
9489 compare(factory.item.title, data.title, "Title does not match data");
95− compare(factory.item.time, timeFormatter.timeString, "Time does not match data");
90+ compare(factory.item.time, i18n.relativeDateTime(data.time), "Time does not match data");
9691 compare(factory.item.body, data.body, "Message does not match data");
9792 compare(factory.item.avatar, data.avatar, "Avatar does not match data");
9893 compare(factory.item.icon, data.icon, "App icon does not match data");
@@ -111,7 +106,7 @@ Item {
111106 menuData.label = data.title;
112107 menuData.sensitive = data.enabled;
113108 menuData.ext = {
114− 'xCanonicalTime': data.time.getTime()*1000,
109+ 'xCanonicalTime': data.time.getTime()*1000, // expected in microseconds
115110 'xCanonicalText': data.body,
116111 'icon': data.avatar,
117112 'xCanonicalAppIcon': data.icon,
@@ -123,11 +118,10 @@ Item {
123118 ]
124119 };
125120 factory.menuData = menuData;
126− timeFormatter.time = data.time.getTime()/1000;
127121
128122 tryCompare(factory.item, "objectName", "textMessage");
129123 compare(factory.item.title, data.title, "Title does not match data");
130− compare(factory.item.time, timeFormatter.timeString, "Time does not match data");
124+ compare(factory.item.time, i18n.relativeDateTime(data.time), "Time does not match data");
131125 compare(factory.item.body, data.body, "Message does not match data");
132126 compare(factory.item.avatar, data.avatar, "Avatar does not match data");
133127 compare(factory.item.icon, data.icon, "App icon does not match data");
@@ -147,7 +141,7 @@ Item {
147141 menuData.label = data.title;
148142 menuData.sensitive = data.enabled;
149143 menuData.ext = {
150− 'xCanonicalTime': data.time.getTime()*1000,
144+ 'xCanonicalTime': data.time.getTime()*1000, // expected in microseconds
151145 'xCanonicalText': data.body,
152146 'icon': data.avatar,
153147 'xCanonicalAppIcon': data.icon,
@@ -162,11 +156,10 @@ Item {
162156 ]
163157 };
164158 factory.menuData = menuData;
165− timeFormatter.time = data.time.getTime()/1000;
166159
167160 tryCompare(factory.item, "objectName", "snapDecision");
168161 compare(factory.item.title, data.title, "Title does not match data");
169− compare(factory.item.time, timeFormatter.timeString, "Time does not match data");
162+ compare(factory.item.time, i18n.relativeDateTime(data.time), "Time does not match data");
170163 compare(factory.item.body, data.body, "Message does not match data");
171164 compare(factory.item.avatar, data.avatar, "Avatar does not match data");
172165 compare(factory.item.icon, data.icon, "App icon does not match data");
tests/qmltests/Panel/tst_ActiveCallHint.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import Ubuntu.Telephony 0.1 as Telephony
tests/qmltests/Panel/tst_IndicatorItem.qml+2−2
@@ -14,10 +14,10 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
20−import Ubuntu.Components 0.1
20+import Ubuntu.Components 1.3
2121import Unity.Test 0.1 as UT
2222import "../../../qml/Panel"
2323
tests/qmltests/Panel/tst_IndicatorItemRow.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import "../../../qml/Panel"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Test 0.1 as UT
2323import Unity.Indicators 0.1 as Indicators
2424
tests/qmltests/Panel/tst_IndicatorPage.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import Unity.Indicators 0.1 as Indicators
tests/qmltests/Panel/tst_IndicatorsBar.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import "../../../qml/Panel"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Test 0.1 as UT
2323import Unity.Indicators 0.1 as Indicators
2424
tests/qmltests/Panel/tst_IndicatorsMenu.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import "../../../qml/Panel"
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Test 0.1 as UT
2323import Unity.Indicators 0.1 as Indicators
2424
tests/qmltests/Panel/tst_MenuContent.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import "../../../qml/Panel"
tests/qmltests/Panel/tst_Panel.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import Unity.Test 0.1
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Application 0.1
2323import Unity.Indicators 0.1 as Indicators
2424import Ubuntu.Telephony 0.1 as Telephony
tests/qmltests/Stages/ApplicationCheckBox.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import Unity.Application 0.1
2121
2222RowLayout {
tests/qmltests/Stages/RecursingChildSessionControl.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Unity.Application 0.1
2121
2222ColumnLayout {
tests/qmltests/Stages/tst_ApplicationWindow.qml+3−3
@@ -14,14 +14,14 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import Unity.Test 0.1 as UT
2121import ".."
2222import "../../../qml/Stages"
23−import Ubuntu.Components 0.1
24−import Ubuntu.Components.ListItems 1.0 as ListItem
23+import Ubuntu.Components 1.3
24+import Ubuntu.Components.ListItems 1.3 as ListItem
2525import Unity.Application 0.1
2626
2727Rectangle {
tests/qmltests/Stages/tst_DesktopStage.qml+84−8
@@ -14,33 +14,40 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 1.1
20−import Ubuntu.Components.ListItems 1.0 as ListItem
19+import Ubuntu.Components 1.3
20+import Ubuntu.Components.ListItems 1.3 as ListItem
2121import Unity.Application 0.1
2222import Unity.Test 0.1
2323import Utils 0.1
2424
2525import "../../../qml/Stages"
26+import "../../../qml/Components"
2627
2728Item {
2829 id: root
2930 width: desktopStageLoader.width + controls.width
3031 height: desktopStageLoader.height
3132
33+ property var greeter: { fullyShown: true }
34+
3235 Binding {
3336 target: MouseTouchAdaptor
3437 property: "enabled"
3538 value: false
3639 }
3740
38− Component.onCompleted: {
41+ Component.onCompleted: resetGeometry()
42+
43+ function resetGeometry() {
3944 // ensures apps which are tested decorations are in view.
45+ WindowStateStorage.clear();
4046 WindowStateStorage.geometry = {
4147 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)),
4248 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)),
4349 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)),
50+ 'gallery-app': Qt.rect(units.gu(51), units.gu(44), units.gu(50), units.gu(40))
4451 }
4552 }
4653
@@ -61,6 +68,7 @@ Item {
6168 Component.onDestruction: {
6269 desktopStageLoader.itemDestroyed = true;
6370 }
71+ orientations: Orientations {}
6472 }
6573 }
6674 }
@@ -110,14 +118,14 @@ Item {
110118
111119 desktopStageLoader.active = true;
112120 tryCompare(desktopStageLoader, "status", Loader.Ready);
121+ root.resetGeometry();
113122 }
114123
115124 function killAllRunningApps() {
116− while (ApplicationManager.count > 1) {
117− var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
118− ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
125+ while (ApplicationManager.count > 0) {
126+ ApplicationManager.stopApplication(ApplicationManager.get(0).appId);
119127 }
120− compare(ApplicationManager.count, 1)
128+ compare(ApplicationManager.count, 0)
121129 }
122130
123131 function waitUntilAppSurfaceShowsUp(appId) {
@@ -210,5 +218,73 @@ Item {
210218 tap(toAppDecoration);
211219 tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true);
212220 }
221+
222+ function test_minimizeApplicationHidesSurface() {
223+ var dashApp = startApplication("unity8-dash");
224+
225+ var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash");
226+ verify(dashDelegate);
227+
228+ findChild(dashDelegate, "decoratedWindow").minimize();
229+ tryCompare(dashApp.session.surface, "visible", false);
230+ }
231+
232+ function test_maximizeApplicationHidesSurfacesBehindIt() {
233+ var dashApp = startApplication("unity8-dash");
234+ var dialerApp = startApplication("dialer-app");
235+ var cameraApp = startApplication("camera-app");
236+
237+ var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash");
238+ verify(dashDelegate);
239+ var dialerDelegate = findChild(desktopStage, "stageDelegate_dialer-app");
240+ verify(dialerDelegate);
241+ var cameraDelegate = findChild(desktopStage, "stageDelegate_camera-app");
242+ verify(cameraDelegate);
243+
244+ // maximize
245+ findChild(dialerDelegate, "decoratedWindow").maximize();
246+ tryCompare(dialerDelegate, "visuallyMaximized", true);
247+
248+ tryCompare(dashApp.session.surface, "visible", false);
249+ compare(cameraApp.session.surface.visible, true);
250+
251+ // restore
252+ findChild(dialerDelegate, "decoratedWindow").maximize();
253+ compare(dashApp.session.surface.visible, true);
254+ compare(cameraApp.session.surface.visible, true);
255+ }
256+
257+ function test_applicationsBecomeVisibleWhenOccludingAppRemoved() {
258+ var dashApp = startApplication("unity8-dash");
259+ var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash");
260+ verify(dashDelegate);
261+
262+ var dialerApp = startApplication("dialer-app");
263+ var dialerDelegate = findChild(desktopStage, "stageDelegate_dialer-app");
264+ verify(dialerDelegate);
265+
266+ var cameraApp = startApplication("camera-app");
267+ var cameraDelegate = findChild(desktopStage, "stageDelegate_camera-app");
268+ verify(cameraDelegate);
269+ findChild(dialerDelegate, "decoratedWindow").maximize();
270+
271+ var galleryApp = startApplication("gallery-app");
272+ var galleryDelegate = findChild(desktopStage, "stageDelegate_gallery-app");
273+ verify(galleryDelegate);
274+ findChild(galleryDelegate, "decoratedWindow").maximize();
275+
276+ tryCompare(dialerDelegate, "visuallyMaximized", true);
277+ tryCompare(galleryDelegate, "visuallyMaximized", true);
278+
279+ tryCompare(dashApp.session.surface, "visible", false);
280+ tryCompare(dialerApp.session.surface, "visible", false);
281+ tryCompare(cameraApp.session.surface, "visible", false);
282+
283+ ApplicationManager.stopApplication("gallery-app");
284+
285+ compare(cameraApp.session.surface.visible, true);
286+ tryCompare(dialerApp.session.surface, "visible", true);
287+ tryCompare(dashApp.session.surface, "visible", false); // still occluded by maximised dialer
288+ }
213289 }
214290}
tests/qmltests/Stages/tst_PhoneStage.qml+6−4
@@ -14,18 +14,21 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
21+import "../../../qml/Components"
2122import "../../../qml/Stages"
22−import Ubuntu.Components 0.1
23+import Ubuntu.Components 1.3
2324import Unity.Application 0.1
2425
2526Item {
2627 width: units.gu(70)
2728 height: units.gu(70)
2829
30+ property var greeter: { fullyShown: true }
31+
2932 PhoneStage {
3033 id: phoneStage
3134 anchors { fill: parent; rightMargin: units.gu(30) }
@@ -34,8 +37,7 @@ Item {
3437 maximizedAppTopMargin: units.gu(3) + units.dp(2)
3538 interactive: true
3639 shellOrientation: Qt.PortraitOrientation
37− shellPrimaryOrientation: Qt.PortraitOrientation
38− nativeOrientation: Qt.PortraitOrientation
40+ orientations: Orientations {}
3941 }
4042
4143 Binding {
tests/qmltests/Stages/tst_SessionContainer.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
2020import Unity.Test 0.1 as UT
21−import Ubuntu.Components 0.1
21+import Ubuntu.Components 1.3
2222import Unity.Application 0.1
2323import "../../../qml/Stages"
2424
tests/qmltests/Stages/tst_Splash.qml+2−2
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
2121import "../../../qml/Stages"
22−import Ubuntu.Components 0.1
22+import Ubuntu.Components 1.3
2323import Unity.Application 0.1
2424
2525Rectangle {
tests/qmltests/Stages/tst_SpreadDelegate.qml+9−5
@@ -14,13 +14,14 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
21+import "../../../qml/Components"
2122import "../../../qml/Stages"
22−import Ubuntu.Components 0.1
23−import Ubuntu.Components.ListItems 1.0 as ListItem
23+import Ubuntu.Components 1.3
24+import Ubuntu.Components.ListItems 1.3 as ListItem
2425import Unity.Application 0.1
2526
2627Rectangle {
@@ -73,8 +74,11 @@ Rectangle {
7374 return Qt.LandscapeOrientation;
7475 }
7576 }
76− shellPrimaryOrientation: Qt.PortraitOrientation
77− nativeOrientation: Qt.PortraitOrientation
77+
78+ orientations: Orientations {
79+ // the default values will do
80+ }
81+
7882 maximizedAppTopMargin: units.gu(3)
7983 Component.onDestruction: {
8084 spreadDelegateLoader.itemDestroyed = true;
tests/qmltests/Stages/tst_SurfaceContainer.qml+2−2
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1
2020import ".."
2121import "../../../qml/Stages"
22−import Ubuntu.Components 0.1
22+import Ubuntu.Components 1.3
2323import Unity.Application 0.1
2424
2525Rectangle {
tests/qmltests/Stages/tst_TabletStage.qml+10−5
@@ -14,14 +14,15 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 1.1
20−import Ubuntu.Components.ListItems 1.0 as ListItem
19+import Ubuntu.Components 1.3
20+import Ubuntu.Components.ListItems 1.3 as ListItem
2121import Unity.Application 0.1
2222import Unity.Test 0.1
2323
2424import "../../../qml/Stages"
25+import "../../../qml/Components"
2526
2627Rectangle {
2728 id: root
@@ -29,6 +30,8 @@ Rectangle {
2930 width: tabletStageLoader.width + controls.width
3031 height: tabletStageLoader.height
3132
33+ property var greeter: { fullyShown: true }
34+
3235 Loader {
3336 id: tabletStageLoader
3437
@@ -50,10 +53,12 @@ Rectangle {
5053 maximizedAppTopMargin: units.gu(3) + units.dp(2)
5154 interactive: true
5255 shellOrientation: Qt.LandscapeOrientation
53− shellPrimaryOrientation: Qt.LandscapeOrientation
54− nativeOrientation: Qt.LandscapeOrientation
5556 nativeWidth: width
5657 nativeHeight: height
58+ orientations: Orientations {
59+ native_: Qt.LandscapeOrientation
60+ primary: Qt.LandscapeOrientation
61+ }
5762 focus: true
5863 }
5964 }
tests/qmltests/Stages/tst_WindowMoveResizeArea.qml → tests/qmltests/Stages/tst_WindowResizeArea.qmlrenamed+56−66
@@ -14,14 +14,14 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.1
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
20−import Unity.Test 0.1 as UT
20+import Unity.Test 0.1
2121import ".."
2222import "../../../qml/Stages"
23−import Ubuntu.Components 0.1
24−import Ubuntu.Components.ListItems 1.0 as ListItem
23+import Ubuntu.Components 1.3
24+import Ubuntu.Components.ListItems 1.3 as ListItem
2525import Unity.Application 0.1
2626
2727Item {
@@ -36,34 +36,41 @@ Item {
3636
3737 Item {
3838 id: fakeWindow
39− property alias minWidth: moveResizeArea.minWidth
40− property alias minHeight: moveResizeArea.minHeight
39+ property alias minWidth: windowResizeArea.minWidth
40+ property alias minHeight: windowResizeArea.minHeight
4141 x: units.gu(20)
4242 y: units.gu(20)
4343 height: units.gu(20)
4444 width: units.gu(20)
4545 property int windowHeight: height
4646 property int windowWidth: width
47− onWindowHeightChanged: height = windowHeight
48− onWindowWidthChanged: width = windowWidth
47+ state: "normal"
4948
50− WindowMoveResizeArea {
51− id: moveResizeArea
49+ function maximize() {
50+ state = "maximized"
51+ }
52+
53+ WindowResizeArea {
54+ id: windowResizeArea
5255 target: fakeWindow
53− resizeHandleWidth: units.gu(0.5)
56+ borderThickness: units.gu(2)
5457 minWidth: units.gu(15)
5558 minHeight: units.gu(10)
5659 windowId: "test-window-id"
5760 }
5861
5962 Rectangle {
60− anchors.fill: moveResizeArea
63+ anchors.fill: windowResizeArea
6164 color: "red"
6265 }
6366
6467 Rectangle {
6568 anchors.fill: fakeWindow
6669 color: "blue"
70+ MouseArea {
71+ anchors.fill: parent
72+ hoverEnabled: true
73+ }
6774 }
6875 }
6976 }
@@ -73,8 +80,13 @@ Item {
7380 sourceComponent: fakeWindowComponent
7481 }
7582
76− UT.UnityTestCase {
77− name: "WindowMoveResizeArea"
83+ MouseTouchEmulationCheckbox {
84+ checked: false
85+ color: "black"
86+ }
87+
88+ UnityTestCase {
89+ name: "WindowResizeArea"
7890 when: windowShown
7991
8092 function init() {
@@ -84,34 +96,6 @@ Item {
8496 fakeWindow.height = units.gu(20)
8597 }
8698
87− function test_dragWindow_data() {
88− return [
89− { tag: "up", dx: 0, dy: units.gu(-10) },
90− { tag: "down", dx: 0, dy: units.gu(10) },
91− { tag: "left", dx: units.gu(-10), dy: 0 },
92− { tag: "right", dx: units.gu(10), dy: 0 },
93− { tag: "right/down", dx: units.gu(10), dy: units.gu(10) },
94− { tag: "left/down", dx: units.gu(-10), dy: units.gu(10) }
95− ]
96− }
97−
98− function test_dragWindow(data) {
99− var initialWindowX = fakeWindow.x;
100− var initialWindowY = fakeWindow.y;
101− var initialWindowWidth = fakeWindow.width
102− var initialWindowHeight = fakeWindow.height
103−
104− var startDragX = initialWindowX + fakeWindow.width / 2;
105− var startDragY = initialWindowY + fakeWindow.height / 2;
106− mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10)
107−
108− tryCompare(fakeWindow, "x", initialWindowX + data.dx)
109− tryCompare(fakeWindow, "y", initialWindowX + data.dy)
110−
111− compare(fakeWindow.height, initialWindowHeight);
112− compare(fakeWindow.width, initialWindowWidth);
113− }
114−
11599 function test_resizeWindowRightBottom_data() {
116100 return [
117101 { tag: "width", dx: units.gu(10), dy: 0 },
@@ -166,30 +150,6 @@ Item {
166150 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
167151 }
168152
169− function test_saveRestorePosition() {
170− var initialWindowX = fakeWindow.x;
171− var initialWindowY = fakeWindow.y;
172− var initialWindowWidth = fakeWindow.width;
173− var initialWindowHeight = fakeWindow.height;
174−
175− var moveDelta = units.gu(5);
176− var startDragX = initialWindowX + fakeWindow.width / 2;
177− var startDragY = initialWindowY + fakeWindow.height / 2;
178− mouseFlick(root, startDragX, startDragY, startDragX + moveDelta, startDragY + moveDelta, true, true, units.gu(.5), 10)
179−
180− tryCompare(fakeWindow, "x", initialWindowX + moveDelta)
181− tryCompare(fakeWindow, "y", initialWindowX + moveDelta)
182−
183− // This will destroy the window and recreate it
184− windowLoader.active = false;
185− waitForRendering(root);
186− windowLoader.active = true;
187−
188− // Make sure it's again where we left it before destroying
189− tryCompare(fakeWindow, "x", initialWindowX + moveDelta)
190− tryCompare(fakeWindow, "y", initialWindowX + moveDelta)
191− }
192−
193153 function test_saveRestoreSize() {
194154 var initialWindowX = fakeWindow.x;
195155 var initialWindowY = fakeWindow.y;
@@ -238,5 +198,35 @@ Item {
238198 tryCompare(fakeWindow, "width", initialWindowWidth);
239199 tryCompare(fakeWindow, "height", initialWindowHeight);
240200 }
201+
202+ function test_saveRestoreMaximized() {
203+ var initialWindowX = fakeWindow.x;
204+ var initialWindowY = fakeWindow.y;
205+
206+ var moveDelta = units.gu(5);
207+
208+ fakeWindow.x = initialWindowX + moveDelta
209+ fakeWindow.y = initialWindowY + moveDelta
210+
211+ // Now change the state to maximized. The window should not keep updating the stored values
212+ fakeWindow.state = "maximized"
213+ fakeWindow.x = 31415 // 0 is too risky to pass the test even when broken
214+ fakeWindow.y = 31415
215+
216+ // This will destroy the window and recreate it
217+ windowLoader.active = false;
218+ waitForRendering(root);
219+ windowLoader.active = true;
220+
221+ // Make sure it's again where we left it in normal state before destroying
222+ tryCompare(fakeWindow, "x", initialWindowX + moveDelta)
223+ tryCompare(fakeWindow, "y", initialWindowX + moveDelta)
224+
225+ // Make sure maximize() has been called after restoring
226+ tryCompare(fakeWindow, "state", "maximized")
227+
228+ // clean up
229+ fakeWindow.state = "normal"
230+ }
241231 }
242232}
tests/qmltests/Tutorial/tst_Tutorial.qml+2−2
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import AccountsService 0.1
2020import IntegratedLightDM 0.1 as LightDM
21−import Ubuntu.Components 1.1
21+import Ubuntu.Components 1.3
2222import Unity.Application 0.1
2323import Unity.Test 0.1 as UT
2424
tests/qmltests/Wizard/tst_Wizard.qml+3−3
@@ -14,12 +14,12 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.3
17+import QtQuick 2.4
1818import QtTest 1.0
1919import AccountsService 0.1
2020import MeeGo.QOfono 0.2
2121import QMenuModel 0.1
22−import Ubuntu.Components 1.1
22+import Ubuntu.Components 1.3
2323import Ubuntu.SystemSettings.SecurityPrivacy 1.0
2424import Unity.Test 0.1 as UT
2525import Wizard 0.1
@@ -96,7 +96,7 @@ Item {
9696 }
9797
9898 Component.onCompleted: {
99− Theme.name = "Ubuntu.Components.Themes.SuruGradient";
99+ theme.name = "Ubuntu.Components.Themes.SuruGradient";
100100 setup();
101101 }
102102
tests/qmltests/tst_DisabledScreenNotice.qmlnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtTest 1.0
19+import Unity.Test 0.1
20+import "../../qml"
21+
22+
23+Item {
24+ id: root
25+ width: units.gu(70)
26+ height: units.gu(70)
27+
28+ DisabledScreenNotice {
29+ anchors.fill: parent
30+ }
31+
32+ UnityTestCase {
33+ id: testCase
34+ name: "DisabledScreenNotice"
35+ when: windowShown
36+ }
37+}
tests/qmltests/tst_OrientedShell.qml+59−5
@@ -14,11 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
1919import QtTest 1.0
20−import Ubuntu.Components 1.1
21−import Ubuntu.Components.ListItems 1.0 as ListItem
20+import Ubuntu.Components 1.3
21+import Ubuntu.Components.ListItems 1.3 as ListItem
2222import Unity.Application 0.1
2323import Unity.Test 0.1
2424import IntegratedLightDM 0.1 as LightDM
@@ -110,6 +110,22 @@ Rectangle {
110110 physicalOrientation180: Qt.LandscapeOrientation
111111 primaryOrientationAngle: 90
112112 }
113+ },
114+ State {
115+ name: "desktop"
116+ PropertyChanges {
117+ target: orientedShellLoader
118+ width: units.gu(100)
119+ height: units.gu(56)
120+ }
121+ PropertyChanges {
122+ target: root
123+ physicalOrientation270: Qt.InvertedPortraitOrientation
124+ physicalOrientation0: Qt.LandscapeOrientation
125+ physicalOrientation90: Qt.PortraitOrientation
126+ physicalOrientation180: Qt.InvertedLandscapeOrientation
127+ primaryOrientationAngle: 0
128+ }
113129 }
114130 ]
115131
@@ -250,7 +266,7 @@ Rectangle {
250266 anchors { left: parent.left; right: parent.right }
251267 activeFocusOnPress: false
252268 text: "Device Name"
253− model: ["mako", "manta", "flo"]
269+ model: ["mako", "manta", "flo", "desktop"]
254270 onSelectedIndexChanged: {
255271 testCase.tearDown();
256272 applicationArguments.deviceName = model[selectedIndex];
@@ -264,6 +280,10 @@ Rectangle {
264280 text: "Usage Mode"
265281 model: ["Staged", "Windowed", "Automatic"]
266282 }
283+ MouseTouchEmulationCheckbox {
284+ checked: true
285+ color: "white"
286+ }
267287 Button {
268288 text: "Switch fullscreen"
269289 activeFocusOnPress: false
@@ -306,12 +326,14 @@ Rectangle {
306326 Row {
307327 Button {
308328 text: "Add mouse"
329+ activeFocusOnPress: false
309330 onClicked: {
310331 UnityInputInfo.inputInfo.addMockMouse()
311332 }
312333 }
313334 Button {
314335 text: "Remove mouse"
336+ activeFocusOnPress: false
315337 onClicked: {
316338 UnityInputInfo.inputInfo.removeMockMouse()
317339 }
@@ -320,17 +342,37 @@ Rectangle {
320342 Row {
321343 Button {
322344 text: "Add kbd"
345+ activeFocusOnPress: false
323346 onClicked: {
324347 UnityInputInfo.inputInfo.addMockKeyboard()
325348 }
326349 }
327350 Button {
351+ activeFocusOnPress: false
328352 text: "Remove kbd"
329353 onClicked: {
330354 UnityInputInfo.inputInfo.removeMockKeyboard()
331355 }
332356 }
333357 }
358+
359+ // Simulates what happens when the shell is moved to an external monitor and back
360+ Button {
361+ id: moveToFromMonitorButton
362+ text: applicationArguments.deviceName === "desktop" ? "Move to " + prevDevName + " screen" : "Move to desktop screen"
363+ activeFocusOnPress: false
364+ property string prevDevName: "mako"
365+ onClicked: {
366+ usageModeSelector.selectedIndex = 2; // "Automatic"
367+
368+ if (applicationArguments.deviceName === "desktop") {
369+ applicationArguments.deviceName = prevDevName;
370+ } else {
371+ prevDevName = applicationArguments.deviceName;
372+ applicationArguments.deviceName = "desktop"
373+ }
374+ }
375+ }
334376 }
335377 }
336378
@@ -798,7 +840,7 @@ Rectangle {
798840 // shell should remain in its primery orientation as the app in the main stage
799841 // is the one that dictates its orientation. In this case it's unity8-dash
800842 // which supports only primary orientation
801− compare(shell.orientation, orientedShell.primaryOrientation);
843+ compare(shell.orientation, orientedShell.orientations.primary);
802844 }
803845
804846 function test_sideStageAppsRemainPortraitInSpread_data() {
@@ -1050,6 +1092,18 @@ Rectangle {
10501092 compare(signalSpy.count, 0);
10511093 }
10521094
1095+ function test_moveToExternalMonitor() {
1096+ loadShell("flo");
1097+
1098+ compare(orientedShell.orientation, Qt.InvertedLandscapeOrientation);
1099+ compare(shell.transformRotationAngle, 90);
1100+
1101+ moveToFromMonitorButton.clicked();
1102+
1103+ tryCompare(orientedShell, "orientation", Qt.LandscapeOrientation);
1104+ tryCompare(shell, "transformRotationAngle" , 0);
1105+ }
1106+
10531107 // angle - rotation angle in degrees clockwise, relative to the primary orientation.
10541108 function rotateTo(angle) {
10551109 switch (angle) {
tests/qmltests/tst_Shell.qml+152−30
@@ -14,13 +14,13 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
1919import AccountsService 0.1
2020import GSettings 1.0
2121import IntegratedLightDM 0.1 as LightDM
22−import Ubuntu.Components 1.1
23−import Ubuntu.Components.ListItems 1.0 as ListItem
22+import Ubuntu.Components 1.3
23+import Ubuntu.Components.ListItems 1.3 as ListItem
2424import Ubuntu.Telephony 0.1 as Telephony
2525import Unity.Application 0.1
2626import Unity.Connectivity 0.1
@@ -29,8 +29,11 @@ import Unity.Notifications 1.0
2929import Unity.Test 0.1
3030import Powerd 0.1
3131import Wizard 0.1 as Wizard
32+import Utils 0.1
3233
3334import "../../qml"
35+import "../../qml/Components"
36+import "../../qml/Components/PanelState"
3437import "Stages"
3538
3639Rectangle {
@@ -58,6 +61,10 @@ Rectangle {
5861
5962 anchors.centerIn: parent
6063
64+ property int shellOrientation: Qt.PortraitOrientation
65+ property int nativeOrientation: Qt.PortraitOrientation
66+ property int primaryOrientation: Qt.PortraitOrientation
67+
6168 state: "phone"
6269 states: [
6370 State {
@@ -74,6 +81,9 @@ Rectangle {
7481 target: shellLoader
7582 width: units.gu(100)
7683 height: units.gu(71)
84+ shellOrientation: Qt.LandscapeOrientation
85+ nativeOrientation: Qt.LandscapeOrientation
86+ primaryOrientation: Qt.LandscapeOrientation
7787 }
7888 },
7989 State {
@@ -96,9 +106,13 @@ Rectangle {
96106 Shell {
97107 id: __shell
98108 usageScenario: usageScenarioSelector.model[usageScenarioSelector.selectedIndex]
99− orientation: Qt.PortraitOrientation
100− primaryOrientation: Qt.PortraitOrientation
101− nativeOrientation: Qt.PortraitOrientation
109+ nativeWidth: width
110+ nativeHeight: height
111+ orientation: shellLoader.shellOrientation
112+ orientations: Orientations {
113+ native_: shellLoader.nativeOrientation
114+ primary: shellLoader.primaryOrientation
115+ }
102116 Component.onDestruction: {
103117 shellLoader.itemDestroyed = true;
104118 }
@@ -302,6 +316,7 @@ Rectangle {
302316 mouseEmulation.checked = true;
303317 tryCompare(shell, "enabled", true); // make sure greeter didn't leave us in disabled state
304318 tearDown();
319+ WindowStateStorage.clear();
305320 }
306321
307322 function loadShell(formFactor) {
@@ -377,6 +392,8 @@ Rectangle {
377392 LightDM.Greeter.authenticate(""); // reset greeter
378393
379394 sessionSpy.clear();
395+
396+ GSettingsController.setLifecycleExemptAppids([]);
380397 }
381398
382399 function killApps() {
@@ -1240,30 +1257,6 @@ Rectangle {
12401257 tryCompare(launcherPanel, "x", -launcherPanel.width);
12411258 }
12421259
1243− function test_background_data() {
1244− return [
1245− {tag: "color", accounts: Qt.resolvedUrl("data:image/svg+xml,<svg><rect width='100%' height='100%' fill='#dd4814'/></svg>"), gsettings: "", output: Qt.resolvedUrl("data:image/svg+xml,<svg><rect width='100%' height='100%' fill='#dd4814'/></svg>")},
1246− {tag: "empty", accounts: "", gsettings: "", output: "defaultBackground"},
1247− {tag: "as-specified", accounts: Qt.resolvedUrl("../data/unity/backgrounds/blue.png"), gsettings: "", output: Qt.resolvedUrl("../data/unity/backgrounds/blue.png")},
1248− {tag: "gs-specified", accounts: "", gsettings: Qt.resolvedUrl("../data/unity/backgrounds/red.png"), output: Qt.resolvedUrl("../data/unity/backgrounds/red.png")},
1249− {tag: "both-specified", accounts: Qt.resolvedUrl("../data/unity/backgrounds/blue.png"), gsettings: Qt.resolvedUrl("../data/unity/backgrounds/red.png"), output: Qt.resolvedUrl("../data/unity/backgrounds/blue.png")},
1250− {tag: "invalid-as", accounts: Qt.resolvedUrl("../data/unity/backgrounds/nope.png"), gsettings: Qt.resolvedUrl("../data/unity/backgrounds/red.png"), output: Qt.resolvedUrl("../data/unity/backgrounds/red.png")},
1251− {tag: "invalid-both", accounts: Qt.resolvedUrl("../data/unity/backgrounds/nope.png"), gsettings: Qt.resolvedUrl("../data/unity/backgrounds/stillnope.png"), output: "defaultBackground"},
1252− ]
1253− }
1254− function test_background(data) {
1255− loadShell("phone");
1256− swipeAwayGreeter();
1257− AccountsService.backgroundFile = data.accounts;
1258− GSettingsController.setPictureUri(data.gsettings);
1259−
1260− if (data.output === "defaultBackground") {
1261− tryCompare(shell, "background", shell.defaultBackground);
1262− } else {
1263− tryCompare(shell, "background", data.output);
1264− }
1265− }
1266−
12671260 function test_tabletLogin_data() {
12681261 return [
12691262 {tag: "auth error", user: "auth-error", loggedIn: false, password: ""},
@@ -1731,5 +1724,134 @@ Rectangle {
17311724
17321725 keyRelease(Qt.Key_Control);
17331726 }
1727+
1728+ // regression test for http://pad.lv/1443319
1729+ function test_closeMaximizedAndRestart() {
1730+ loadDesktopShellWithApps();
1731+
1732+ var appRepeater = findChild(shell, "appRepeater")
1733+ var appId = ApplicationManager.get(0).appId;
1734+ var appDelegate = appRepeater.itemAt(0);
1735+ var maximizeButton = findChild(appDelegate, "maximizeWindowButton");
1736+
1737+ tryCompare(appDelegate, "state", "normal");
1738+ tryCompare(PanelState, "buttonsVisible", false)
1739+
1740+ mouseClick(maximizeButton, maximizeButton.width / 2, maximizeButton.height / 2);
1741+ tryCompare(appDelegate, "state", "maximized");
1742+ tryCompare(PanelState, "buttonsVisible", true)
1743+
1744+ ApplicationManager.stopApplication(appId);
1745+ tryCompare(PanelState, "buttonsVisible", false)
1746+
1747+ ApplicationManager.startApplication(appId);
1748+ tryCompare(PanelState, "buttonsVisible", true)
1749+ }
1750+
1751+ function test_newAppHasValidGeometry() {
1752+ loadDesktopShellWithApps();
1753+ var appRepeater = findChild(shell, "appRepeater");
1754+ var appId = ApplicationManager.get(0).appId;
1755+ var appDelegate = appRepeater.itemAt(0);
1756+
1757+ var resizeArea = findChild(appDelegate, "windowResizeArea");
1758+ var priv = findInvisibleChild(resizeArea, "priv");
1759+
1760+ // Make sure windows are at 0,0 or greater and they have a size that's > 0
1761+ compare(priv.normalX >= 0, true)
1762+ compare(priv.normalY >= 0, true)
1763+ compare(priv.normalWidth > 0, true)
1764+ compare(priv.normalHeight > 0, true)
1765+ }
1766+
1767+ // bug http://pad.lv/1431566
1768+ function test_switchToStagedHidesPanelButtons() {
1769+ loadDesktopShellWithApps();
1770+ var appRepeater = findChild(shell, "appRepeater")
1771+ var appId = ApplicationManager.get(0).appId;
1772+ var appDelegate = appRepeater.itemAt(0);
1773+ var panelButtons = findChild(shell, "panelWindowControlButtons")
1774+
1775+ tryCompare(appDelegate, "state", "normal");
1776+ tryCompare(panelButtons, "visible", false);
1777+
1778+ appDelegate.maximize(false);
1779+ tryCompare(panelButtons, "visible", true);
1780+
1781+ shell.usageScenario = "phone";
1782+ waitForRendering(shell);
1783+ tryCompare(panelButtons, "visible", false);
1784+
1785+ shell.usageScenario = "desktop";
1786+ waitForRendering(shell);
1787+ tryCompare(panelButtons, "visible", true);
1788+ }
1789+
1790+ function test_lockingGreeterHidesPanelButtons() {
1791+ loadDesktopShellWithApps();
1792+ var appRepeater = findChild(shell, "appRepeater")
1793+ var appId = ApplicationManager.get(0).appId;
1794+ var appDelegate = appRepeater.itemAt(0);
1795+ var panelButtons = findChild(shell, "panelWindowControlButtons")
1796+
1797+ tryCompare(appDelegate, "state", "normal");
1798+ tryCompare(panelButtons, "visible", false);
1799+
1800+ appDelegate.maximize(false);
1801+ tryCompare(panelButtons, "visible", true);
1802+
1803+ LightDM.Greeter.showGreeter();
1804+ waitForRendering(shell);
1805+ tryCompare(panelButtons, "visible", false);
1806+
1807+ LightDM.Greeter.hideGreeter();
1808+ waitForRendering(shell);
1809+ tryCompare(panelButtons, "visible", true);
1810+ }
1811+
1812+ function test_lifecyclePolicyForNonTouchApp_data() {
1813+ return [
1814+ {tag: "phone", formFactor: "phone", usageScenario: "phone"},
1815+ {tag: "tablet", formFactor: "tablet", usageScenario: "tablet"}
1816+ ]
1817+ }
1818+
1819+ function test_lifecyclePolicyForNonTouchApp(data) {
1820+ loadShell(data.formFactor);
1821+ shell.usageScenario = data.usageScenario;
1822+
1823+ var app1 = ApplicationManager.startApplication("libreoffice");
1824+ waitUntilAppWindowIsFullyLoaded(app1);
1825+ var app2 = ApplicationManager.startApplication("dialer-app");
1826+ waitUntilAppWindowIsFullyLoaded(app2);
1827+
1828+ // Make sure app1 is unfocused but still running
1829+ compare(app1.session.surface.activeFocus, false);
1830+ compare(app1.isTouchApp, false); // sanity check our mock, which sets this for us
1831+ compare(app1.requestedState, ApplicationInfoInterface.RequestedRunning);
1832+ }
1833+
1834+ function test_lifecyclePolicyExemption_data() {
1835+ return [
1836+ {tag: "phone", formFactor: "phone", usageScenario: "phone", suspendsApps: true},
1837+ {tag: "tablet", formFactor: "tablet", usageScenario: "tablet", suspendsApps: true}
1838+ ]
1839+ }
1840+
1841+ function test_lifecyclePolicyExemption(data) {
1842+ loadShell(data.formFactor);
1843+ shell.usageScenario = data.usageScenario;
1844+
1845+ GSettingsController.setLifecycleExemptAppids(["webbrowser-app"]);
1846+
1847+ var app1 = ApplicationManager.startApplication("webbrowser-app");
1848+ waitUntilAppWindowIsFullyLoaded(app1);
1849+ var app2 = ApplicationManager.startApplication("dialer-app");
1850+ waitUntilAppWindowIsFullyLoaded(app2);
1851+
1852+ // Make sure app1 is unfocused but still running
1853+ compare(app1.session.surface.activeFocus, false);
1854+ compare(app1.requestedState, ApplicationInfoInterface.RequestedRunning);
1855+ }
17341856 }
17351857}
tests/qmltests/tst_ShellWithPin.qml+2−2
@@ -14,8 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
18−import Ubuntu.Components 1.0
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
1919import QtTest 1.0
2020import AccountsService 0.1
2121import GSettings 1.0
tests/qmltests/utils/Unity/Test/MockObjectForInstanceOfTest.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919Rectangle {
2020 property int dummy
tests/qmltests/utils/Unity/Test/MockObjectForInstanceOfTestChild.qml+1−1
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818
1919MockObjectForInstanceOfTest {
2020 property int dummy2
tests/qmltests/utils/Unity/Test/tst_UnityTest.qml+1−1
@@ -15,7 +15,7 @@
1515 */
1616
1717
18−import QtQuick 2.0
18+import QtQuick 2.4
1919import QtTest 1.0
2020import Unity.Test 0.1
2121
tests/utils/modules/Unity/Test/MouseTouchEmulationCheckbox.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.1
19+import Ubuntu.Components 1.3
2020import Unity.Test 0.1
2121
2222RowLayout {
tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp−2
@@ -27,12 +27,10 @@ TouchEventSequenceWrapper::TouchEventSequenceWrapper(QTest::QTouchEventSequence
2727void TouchEventSequenceWrapper::commit(bool processEvents)
2828{
2929 m_eventSequence.commit(processEvents);
30−#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
3130 if (m_item->window()) {
3231 QQuickWindowPrivate *wp = QQuickWindowPrivate::get(m_item->window());
3332 wp->flushDelayedTouchEvent();
3433 }
35−#endif
3634}
3735
3836void TouchEventSequenceWrapper::move(int touchId, int x, int y)
tests/utils/modules/Unity/Test/UnityTestCase.qml+2−2
@@ -14,9 +14,9 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.4
1818import QtTest 1.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.3
2020import Unity.Test 0.1 as UT
2121
2222TestCase {