Merge lp:~bzoltan/ubuntu-ui-toolkit/landing-2015-09-04 into lp:ubuntu-ui-toolkit

Proposed by Zoltan Balogh
Status: Merged
Approved by: Zoltan Balogh
Approved revision: 1629
Merged at revision: 1224
Proposed branch: lp:~bzoltan/ubuntu-ui-toolkit/landing-2015-09-04
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 9558 lines (+6169/-1099)
129 files modified
.bzrignore (+11/-11)
.qmake.conf (+4/-0)
components.api (+44/-31)
debian/changelog (+58/-0)
debian/control (+5/-0)
documentation/documentation.pro (+1/-1)
documentation/ubuntu-ui-toolkit-common.qdocconf (+1/-1)
examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml (+23/-2)
features/ubuntu_enable_testing.prf (+1/-1)
features/ubuntu_qml_plugin.prf (+52/-51)
po/po.pro (+1/-1)
src/Ubuntu/Components/1.1/Haptics.qml (+0/-91)
src/Ubuntu/Components/1.2/ActionItem.qml (+0/-96)
src/Ubuntu/Components/1.2/TextField.qml (+1/-1)
src/Ubuntu/Components/1.2/TextInputPopover.qml (+1/-0)
src/Ubuntu/Components/1.2/ToolbarButton.qml (+1/-0)
src/Ubuntu/Components/1.3/AbstractButton.qml (+0/-109)
src/Ubuntu/Components/1.3/ActionItem.qml (+0/-96)
src/Ubuntu/Components/1.3/AdaptivePageLayout.qml (+266/-30)
src/Ubuntu/Components/1.3/AppHeader.qml (+1/-6)
src/Ubuntu/Components/1.3/Button.qml (+1/-1)
src/Ubuntu/Components/1.3/ComboButton.qml (+1/-0)
src/Ubuntu/Components/1.3/Header.qml (+0/-39)
src/Ubuntu/Components/1.3/MainView.qml (+0/-3)
src/Ubuntu/Components/1.3/MainViewBase.qml (+24/-27)
src/Ubuntu/Components/1.3/PageColumn.qml (+16/-11)
src/Ubuntu/Components/1.3/PageColumnsLayout.qml (+115/-0)
src/Ubuntu/Components/1.3/PageWrapper.qml (+25/-2)
src/Ubuntu/Components/1.3/PageWrapperUtils.js (+167/-0)
src/Ubuntu/Components/1.3/TextField.qml (+2/-2)
src/Ubuntu/Components/ComponentModule.pro (+7/-8)
src/Ubuntu/Components/ListItems/1.3/SingleControl.qml (+2/-1)
src/Ubuntu/Components/Popups/1.3/Popover.qml (+1/-1)
src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml (+14/-1)
src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml (+0/-2)
src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml (+0/-56)
src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml (+0/-124)
src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml (+65/-0)
src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml (+1/-1)
src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro (+0/-2)
src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp (+7/-7)
src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h (+1/-1)
src/Ubuntu/Components/plugin/i18n.cpp (+74/-0)
src/Ubuntu/Components/plugin/i18n.h (+1/-0)
src/Ubuntu/Components/plugin/plugin.cpp (+18/-0)
src/Ubuntu/Components/plugin/plugin.pri (+9/-2)
src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp (+2/-3)
src/Ubuntu/Components/plugin/privates/listitemdragarea.h (+1/-1)
src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp (+106/-0)
src/Ubuntu/Components/plugin/sortfiltermodel.cpp (+6/-3)
src/Ubuntu/Components/plugin/timeutils_p.h (+24/-0)
src/Ubuntu/Components/plugin/ucabstractbutton.cpp (+156/-0)
src/Ubuntu/Components/plugin/ucabstractbutton.h (+64/-0)
src/Ubuntu/Components/plugin/ucaction.cpp (+5/-5)
src/Ubuntu/Components/plugin/ucaction.h (+8/-7)
src/Ubuntu/Components/plugin/ucactioncontext.cpp (+6/-1)
src/Ubuntu/Components/plugin/ucactioncontext.h (+3/-2)
src/Ubuntu/Components/plugin/ucactionitem.cpp (+316/-0)
src/Ubuntu/Components/plugin/ucactionitem.h (+79/-0)
src/Ubuntu/Components/plugin/uchaptics.cpp (+179/-0)
src/Ubuntu/Components/plugin/uchaptics.h (+78/-0)
src/Ubuntu/Components/plugin/uclistitem.cpp (+134/-22)
src/Ubuntu/Components/plugin/uclistitem.h (+76/-1)
src/Ubuntu/Components/plugin/uclistitem_p.h (+15/-6)
src/Ubuntu/Components/plugin/uclistitemstyle.cpp (+38/-9)
src/Ubuntu/Components/plugin/uclistitemstyle.h (+6/-0)
src/Ubuntu/Components/plugin/ucqquickimageextension.cpp (+23/-3)
src/Ubuntu/Components/plugin/ucstatesaver.cpp (+2/-2)
src/Ubuntu/Components/plugin/ucubuntushape.cpp (+45/-34)
src/Ubuntu/Components/plugin/ucubuntushape.h (+0/-1)
src/Ubuntu/Components/plugin/ucunits.cpp (+46/-5)
src/Ubuntu/Components/plugin/ucunits.h (+1/-0)
src/Ubuntu/Components/plugin/ucviewitemsattached.cpp (+141/-1)
src/Ubuntu/Components/qmldir (+2/-8)
tests/apicheck/apicheck.cpp (+8/-4)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_tabbar.py (+6/-1)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textarea.py (+16/-20)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py (+34/-48)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_toolbar.py (+1/-1)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py (+5/-1)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.1.3.qml (+62/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.new_header.1.3.qml (+43/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py (+6/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.1.0.qml (+37/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.1.3.qml (+37/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py (+15/-31)
tests/resources/listitems/ListItemExpansion.qml (+121/-0)
tests/unit/add_makecheck.pri (+12/-1)
tests/unit/custom_qpa/README (+15/-0)
tests/unit/custom_qpa/custom.json (+3/-0)
tests/unit/custom_qpa/custom_qpa.pro (+15/-0)
tests/unit/custom_qpa/main.cpp (+54/-0)
tests/unit/custom_qpa/qcustombackingstore.cpp (+64/-0)
tests/unit/custom_qpa/qcustombackingstore.h (+55/-0)
tests/unit/custom_qpa/qcustomintegration.cpp (+112/-0)
tests/unit/custom_qpa/qcustomintegration.h (+74/-0)
tests/unit/runtest.sh (+2/-0)
tests/unit/tst_components/tst_action.qml (+16/-0)
tests/unit/tst_components/tst_actionitem.qml (+13/-5)
tests/unit/tst_i18n/tst_i18n.pro (+3/-18)
tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/LocalizedApp.qml (+43/-1)
tests/unit/tst_i18n/tst_i18n_LocalizedApp/src/tst_i18n_LocalizedApp.cpp (+5/-5)
tests/unit/tst_i18n/tst_i18n_LocalizedApp/tst_i18n_LocalizedApp.pro (+17/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/po/en_US.po (+54/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/src/RelativeTime.qml (+71/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/src/tst_i18n_RelativeTime.cpp (+202/-0)
tests/unit/tst_i18n/tst_i18n_RelativeTime/tst_i18n_RelativeTime.pro (+17/-0)
tests/unit/tst_performance/AbstractButton13Grid.qml (+30/-0)
tests/unit/tst_performance/AbstractButtonGrid.qml (+30/-0)
tests/unit/tst_performance/tst_performance.cpp (+2/-0)
tests/unit/tst_performance/tst_performance.pro (+3/-1)
tests/unit/tst_units/dpr1/dpr1.pro (+3/-0)
tests/unit/tst_units/dpr2/dpr2.pro (+3/-0)
tests/unit/tst_units/dpr2/tst_units_dpr2.cpp (+143/-0)
tests/unit/tst_units/dpr3/dpr3.pro (+3/-0)
tests/unit/tst_units/dpr3/tst_units_dpr3.cpp (+88/-0)
tests/unit/tst_units/tst_units.pro (+6/-3)
tests/unit/unit.pro (+3/-1)
tests/unit_x11/tst_components/ListItemTestCase.qml (+6/-0)
tests/unit_x11/tst_components/ListItemTestCase13.qml (+143/-0)
tests/unit_x11/tst_components/tst_abstractbutton13.qml (+115/-0)
tests/unit_x11/tst_components/tst_adaptivepagelayout.qml (+63/-0)
tests/unit_x11/tst_components/tst_adaptivepagelayout_configuration.qml (+229/-0)
tests/unit_x11/tst_components/tst_listitem.qml (+1/-21)
tests/unit_x11/tst_components/tst_listitem13.qml (+1211/-0)
tests/unit_x11/tst_components/tst_listitem_expansion.qml (+199/-0)
tests/unit_x11/tst_components/tst_listitem_extras.qml (+28/-2)
tests/unit_x11/tst_components/tst_multicolumnheader.qml (+37/-1)
ubuntu-sdk.pro (+1/-1)
To merge this branch: bzr merge lp:~bzoltan/ubuntu-ui-toolkit/landing-2015-09-04
Reviewer Review Type Date Requested Status
Ubuntu SDK team Pending
Review via email: mp+270197@code.launchpad.net

Commit message

Landing 2015.09.04

Description of the change

Landing 2015.09.04

To post a comment you must log in.
1630. By Zoltan Balogh

Cope with different AbstractButton class name in 1.3

1631. By Zoltan Balogh

license fix

1632. By Zoltan Balogh

update

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2015-05-20 14:47:16 +0000
3+++ .bzrignore 2015-09-08 04:09:38 +0000
4@@ -1,25 +1,25 @@
5+.obj
6+.pch
7+.qmake.cache
8+.rcc
9+qml
10+
11 Makefile*
12-src/Makefile*
13-src/Ubuntu/Components/Makefile*
14-src/Ubuntu/Components/plugin/Makefile*
15-src/Ubuntu/Components/plugin/qrc_plugin.cpp
16-src/Ubuntu/Components/Themes/Makefile*
17-src/Ubuntu/Components/Layouts/Makefile*
18-src/Ubuntu/Components/PerformanceMetrics/Makefile*
19-src/Ubuntu/Test/Makefile*
20 documentation/html/*
21 *.moc
22 moc_*.cpp
23 qrc_tst_*.cpp
24 tests/test_tst_*.xml
25 tests/tst_*.qml.xml
26-tests/unit*/tst_*/tst_[^.]*
27+tests/unit*/tst_*/tst_*
28+tests/unit/tst_*/tst_*/tst_*
29 tests/unit*/testparser/testparser
30 plugins.qmltypes
31 po/*.mo
32 examples/ubuntu-ui-toolkit-gallery/po/*.mo
33-tests/unit/tst_i18n/locale/en/LC_MESSAGES/*.mo
34+tests/unit/tst_i18n/tst_*/*/share/locale/en/LC_MESSAGES/*.mo
35+tests/unit/tst_i18n/*/share/locale/en/LC_MESSAGES/*.mo
36+tests/unit/tst_units/dpr*/dpr*
37 tests/apicheck/apicheck
38 tests/launcher/launcher
39 build_paths.inc
40-tests/unit/tst_i18n/localizedApp/share/locale/en/LC_MESSAGES/localizedApp.mo
41
42=== modified file '.qmake.conf'
43--- .qmake.conf 2015-05-18 09:53:55 +0000
44+++ .qmake.conf 2015-09-08 04:09:38 +0000
45@@ -12,3 +12,7 @@
46
47 ROOT_SOURCE_DIR=$$PWD
48 ROOT_BUILD_DIR=$$shadowed($$PWD)
49+
50+exists($$PWD/../qt.pro) {
51+ CONFIG += build_with_qt
52+}
53
54=== modified file 'components.api'
55--- components.api 2015-08-12 09:55:50 +0000
56+++ components.api 2015-09-08 04:09:38 +0000
57@@ -4,10 +4,10 @@
58 signal pressAndHold()
59 property bool pressed
60 Ubuntu.Components.AbstractButton 1.3: ActionItem
61- property bool hovered
62+ readonly property bool hovered
63 signal clicked()
64 signal pressAndHold()
65- property bool pressed
66+ readonly property bool pressed
67 Ubuntu.Components.Action 1.3 1.0 0.1: QtObject
68 property string description
69 property bool enabled
70@@ -43,14 +43,8 @@
71 property string iconName
72 property url iconSource
73 signal triggered(var value)
74- function var trigger(var value)
75- property string text
76-Ubuntu.Components.ActionItem 1.3: StyledItem
77- property Action action
78- property string iconName
79- property url iconSource
80- signal triggered(var value)
81- function var trigger(var value)
82+ function trigger(var value)
83+ function trigger()
84 property string text
85 Ubuntu.Components.ActionList 1.0 0.1: QtObject
86 readonly property Action actions
87@@ -82,6 +76,8 @@
88 property bool onScreen
89 property bool running
90 Ubuntu.Components.AdaptivePageLayout 1.3: PageTreeNode
91+ readonly property int columns
92+ readonly property PageColumnsLayout layouts
93 function var addPageToCurrentColumn(var sourcePage, var page, var properties)
94 function var addPageToNextColumn(var sourcePage, var page, var properties)
95 function var removePages(var page)
96@@ -92,6 +88,7 @@
97 property bool enabled
98 readonly property int error
99 property string message
100+ signal statusChanged(Operation operation)
101 function save()
102 function cancel()
103 function reset()
104@@ -305,6 +302,9 @@
105 Ubuntu.Components.ListItems.Divider 1.0 0.1: QQuickImageBase
106 property FillMode fillMode
107 property HAlignment horizontalAlignment
108+ signal horizontalAlignmentChanged(HAlignment alignment)
109+ signal verticalAlignmentChanged(VAlignment alignment)
110+ signal mipmapChanged(bool )
111 property bool mipmap
112 readonly property double paintedHeight
113 readonly property double paintedWidth
114@@ -312,6 +312,9 @@
115 Ubuntu.Components.ListItems.Divider 1.3: QQuickImageBase
116 property FillMode fillMode
117 property HAlignment horizontalAlignment
118+ signal horizontalAlignmentChanged(HAlignment alignment)
119+ signal verticalAlignmentChanged(VAlignment alignment)
120+ signal mipmapChanged(bool )
121 property bool mipmap
122 readonly property double paintedHeight
123 readonly property double paintedWidth
124@@ -361,10 +364,11 @@
125 Ubuntu.Components.FilterBehavior 1.1: QtObject
126 property QRegExp pattern
127 property string property
128-Ubuntu.Components.Haptics 1.0 0.1: Object singleton
129- readonly property HapticsEffect effect
130+Ubuntu.Components.Haptics 1.0 0.1: QtObject singleton
131+ readonly property QtObject effect
132 readonly property bool enabled
133- function var play(var customEffect)
134+ function play(var customEffect)
135+ function play()
136 Ubuntu.Components.ListItems.Header 1.0 0.1: Item
137 property string text
138 Ubuntu.Components.Header 1.0 0.1: AppHeader
139@@ -385,22 +389,6 @@
140 property bool useDeprecatedToolbar
141 Ubuntu.Components.ListItems.Header 1.3: Item
142 property string text
143-Ubuntu.Components.Header 1.3: AppHeader
144- property string _for_autopilot
145- property var actions
146- property bool animate
147- property QtObject config
148- property Item contents
149- property color dividerColor
150- property Flickable flickable
151- function var show()
152- function var hide()
153- readonly property bool moving
154- property var pageStack
155- property color panelColor
156- property var tabsModel
157- property string title
158- property bool useDeprecatedToolbar
159 Ubuntu.Components.Icon 1.0 0.1: Item
160 property color color
161 property color keyColor
162@@ -466,6 +454,7 @@
163 property bool selected
164 property ListItemActions trailingActions
165 Ubuntu.Components.ListItem 1.3: ListItem
166+ readonly property UCListItemExpansion expansion
167 Ubuntu.Components.ListItemActions 1.2: QtObject
168 readonly property Action actions
169 default readonly property QtObject data
170@@ -485,6 +474,7 @@
171 readonly property bool animatePanels
172 property Item dragPanel
173 property PropertyAnimation dropAnimation
174+ readonly property Flickable flickable 1.3
175 readonly property int listItemIndex 1.3
176 function swipeEvent(SwipeEvent event)
177 function rebound()
178@@ -528,6 +518,7 @@
179 signal clicked(QQuickMouseEvent mouse, Item host)
180 signal pressAndHold(QQuickMouseEvent mouse, Item host)
181 signal doubleClicked(QQuickMouseEvent mouse, Item host)
182+ signal positionChanged(QQuickMouseEvent mouse, Item host)
183 signal entered(QQuickMouseEvent event, Item host)
184 signal exited(QQuickMouseEvent event, Item host)
185 property Priority priority
186@@ -603,6 +594,14 @@
187 property Flickable flickable
188 readonly property PageHeadConfiguration head
189 property string title
190+Ubuntu.Components.PageColumn 1.3: QtObject
191+ property bool fillWidth
192+ property double maximumWidth
193+ property double minimumWidth
194+ property double preferredWidth
195+Ubuntu.Components.PageColumnsLayout 1.3: QtObject
196+ default readonly property PageColumn data
197+ property bool when
198 Ubuntu.Components.PageHeadConfiguration 1.1: Object
199 readonly property Action actions
200 property Action backAction
201@@ -1222,14 +1221,16 @@
202 property string iconName
203 property url iconSource
204 signal triggered(var value)
205- function var trigger(var value)
206+ function trigger(var value)
207+ function trigger()
208 property string text
209 Ubuntu.Components.ToolbarButton 1.3: StyledItem
210 property Action action
211 property string iconName
212 property url iconSource
213 signal triggered(var value)
214- function var trigger(var value)
215+ function trigger(var value)
216+ function trigger()
217 property string text
218 Ubuntu.Components.ToolbarItems 1.0 0.1: Item
219 property Item back
220@@ -1246,6 +1247,9 @@
221 UCListItemDivider: Item
222 property color colorFrom
223 property color colorTo
224+UCListItemExpansion: QtObject
225+ property bool expanded
226+ property double height
227 UCStateSaverAttached: QtObject
228 property bool enabled
229 property string properties
230@@ -1393,6 +1397,14 @@
231 signal dragUpdated(ListItemDrag event)
232 property bool selectMode
233 property QList<int> selectedIndices
234+Ubuntu.Components.ViewItems 1.3: ViewItems
235+ property QList<int> expandedIndices
236+ property int expansionFlags
237+ signal expandedIndicesChanged(QList<int> indices)
238+Ubuntu.Components.ViewItems.ExpansionFlag: Enum
239+ CollapseOnOutsidePress
240+ Exclusive
241+ UnlockExpanded
242 Ubuntu.Components.i18n 1.0 0.1: QtObject
243 property string domain
244 property string language
245@@ -1405,3 +1417,4 @@
246 function string dctr(string domain, string context, string text)
247 function string tag(string text)
248 function string tag(string context, string text)
249+ function string relativeDateTime(QDateTime datetime)
250
251=== modified file 'debian/changelog'
252--- debian/changelog 2015-08-24 20:49:45 +0000
253+++ debian/changelog 2015-09-08 04:09:38 +0000
254@@ -1,3 +1,61 @@
255+ubuntu-ui-toolkit (1.3.1627+15.10.20150904-0ubuntu1) UNRELEASED; urgency=medium
256+
257+ [ Zsombor Egri ]
258+ * Implement list item expansion.
259+ * Turn AdaptivePageLayout page creation to be asynchronous.
260+ * Fix ListItem swipe handling when gesture is initiated over an overlay
261+ MouseArea which does not accept pressed event. Fixes LP: #1484545
262+ * AbstractButton to C++. Fixes LP: #1365471, LP: #1458028
263+ * Haptics singleton moved to C++.
264+ * ActionItem moved to C++.
265+ * Making columns resizable in an AdaptivePageLayout.
266+ * Introducing column configuration into AdaptivePageLayout.
267+
268+ [ Benjamin Zeller ]
269+ * Fix build inside qt and shadowbuild.
270+
271+ [ Tim Peeters ]
272+ * Remove old and unused header-related files, and update unit test filenames.
273+ * Don't unset the subheader style when Page.head changes because that unsets
274+ the parent of Page.head.contents. Fixes LP: #1488922
275+ * Fix the theming of the MainView.
276+ * Fix the background color of the overflow panel.
277+
278+ [ Christian Dywan ]
279+ * Include change signals with arguments in .api.
280+ * A public QML type with no version is an error. Rather than silently breaking
281+ as QML does normally at least apicheck can make this fatal.
282+ * UbuntuShape shouldn't emit redundant deprecation warnings. Fixes LP: #1481791
283+ * Update .bzrignore to new upstream style layout. Fixes LP: #1433308
284+ * Revert unnecessary change of Popover minimumWidth. Fixes LP: #1483708
285+
286+ [ Ken VanDine ]
287+ * Fixed a few typos in the api docs for StateSaver.
288+
289+ [ Olivier Tilloy ]
290+ * Take custom key indexes into account to allow sorting on custom roles.
291+ Fixes LP: #1485674
292+
293+ [ Albert Astals Cid ]
294+ * Properly free shapeTextures[index] The old code assumes that the UbuntuShape
295+ will still be around when the opengl context is destroyed, but that seldom
296+ happens so connect the signal to a lambda that will be there and does the
297+ cleanup properly. Without this patch testDirectionalDragArea from unity8 was
298+ hitting the qFatal because it ran out of space in shapeTextures.
299+
300+ [ Richard Huddie ]
301+ * Remove all usage of the autopilot simulated keyboard when the OSK is being
302+ used. Fixes LP: 31483668
303+
304+ [ Gerry Boland ]
305+ * Compensate for Qt's device pixel ratio multiplier.
306+ Fixes: LP: #1207270, LP: #1275748, LP: #1468402
307+
308+ [ Nick Dedekind ]
309+ * Added relative date time i18n.
310+
311+ -- Zoltán Balogh <zoltan@bakter.hu> Fri, 04 Sep 2015 19:25:03 +0300
312+
313 ubuntu-ui-toolkit (1.3.1603+15.10.20150824.1-0ubuntu1) wily; urgency=medium
314
315 [ CI Train Bot ]
316
317=== modified file 'debian/control'
318--- debian/control 2015-07-10 05:40:21 +0000
319+++ debian/control 2015-09-08 04:09:38 +0000
320@@ -45,6 +45,11 @@
321 suru-icon-theme,
322 uuid-runtime,
323 python3-sphinx,
324+ libfontconfig1-dev,
325+ libfreetype6-dev,
326+ libmtdev-dev,
327+ libudev-dev,
328+ libxrender-dev
329 Standards-Version: 3.9.4
330 Homepage: https://launchpad.net/ubuntu-ui-toolkit
331 # If you aren't a member of ~ubuntu-sdk-team but need to upload packaging
332
333=== modified file 'documentation/documentation.pro'
334--- documentation/documentation.pro 2015-06-02 15:47:45 +0000
335+++ documentation/documentation.pro 2015-09-08 04:09:38 +0000
336@@ -17,7 +17,7 @@
337 generate_docs.commands = cd $$ROOT_SOURCE_DIR; SRC=$$ROOT_SOURCE_DIR/documentation BLD=$$ROOT_BUILD_DIR/documentation $$ROOT_SOURCE_DIR/documentation/docs.sh \'$$QDOC\' \'$$QHELPGENERATOR\' $$DOC_PATH
338
339 #install the online docs only when building outside of Qt
340-force_independent: {
341+!build_with_qt{
342 install_docs.files = $$shadowed($$ROOT_SOURCE_DIR)/documentation/html
343 install_docs.path = /usr/share/ubuntu-ui-toolkit/doc
344 install_docs.CONFIG += no_check_exist directory no_build
345
346=== modified file 'documentation/ubuntu-ui-toolkit-common.qdocconf'
347--- documentation/ubuntu-ui-toolkit-common.qdocconf 2015-07-24 18:00:54 +0000
348+++ documentation/ubuntu-ui-toolkit-common.qdocconf 2015-09-08 04:09:38 +0000
349@@ -26,7 +26,7 @@
350 sources.fileextensions = "*.qml *.qdoc *.cpp *.js"
351 headers.fileextensions = "*.h"
352 # exclude qml files that have the component documented in a separate qdoc file
353-excludefiles = $BLD/../src/Ubuntu/Components/MainView.qml
354+excludefiles += $BLD/../src/Ubuntu/Components/1.3/PageWrapperUtils.js
355 outputdir = $BLD/html
356 outputformats = HTML
357 version = 1.2
358
359=== modified file 'examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml'
360--- examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml 2015-08-07 13:48:39 +0000
361+++ examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml 2015-09-08 04:09:38 +0000
362@@ -37,6 +37,28 @@
363 anchors.fill: parent
364 primaryPage: mainPage
365
366+ layouts: [
367+ PageColumnsLayout {
368+ when: layout.width > units.gu(80)
369+ PageColumn {
370+ minimumWidth: units.gu(30)
371+ maximumWidth: units.gu(50)
372+ preferredWidth: units.gu(40)
373+ }
374+ PageColumn {
375+ fillWidth: true
376+ }
377+ },
378+ // configure single column mode so we can only size it to minimum 20 GU
379+ PageColumnsLayout {
380+ when: true
381+ PageColumn {
382+ minimumWidth: units.gu(20)
383+ fillWidth: true
384+ }
385+ }
386+ ]
387+
388 Page {
389 id: mainPage
390 title: "Ubuntu UI Toolkit"
391@@ -74,9 +96,8 @@
392 selected: index === widgetList.currentIndex
393 onClicked: {
394 var source = Qt.resolvedUrl(model.source);
395- var newPage = layout.addPageToNextColumn(mainPage, source);
396+ layout.addPageToNextColumn(mainPage, source, {title: model.label});
397
398- newPage.title = model.label;
399 widgetList.currentIndex = index;
400 }
401 }
402
403=== modified file 'features/ubuntu_enable_testing.prf'
404--- features/ubuntu_enable_testing.prf 2015-05-19 07:55:27 +0000
405+++ features/ubuntu_enable_testing.prf 2015-09-08 04:09:38 +0000
406@@ -1,6 +1,6 @@
407 instbase = $$ROOT_BUILD_DIR/qml
408
409-force_independent: {
410+!build_with_qt {
411 # These bizarre rules copy the files to the build directory
412
413 defineReplace(qmlModStripSrcDir) {
414
415=== modified file 'features/ubuntu_qml_plugin.prf'
416--- features/ubuntu_qml_plugin.prf 2015-07-30 13:47:23 +0000
417+++ features/ubuntu_qml_plugin.prf 2015-09-08 04:09:38 +0000
418@@ -1,64 +1,65 @@
419 load(qml_plugin)
420 CONFIG -= hide_symbols
421
422-
423 load(ubuntu_enable_testing)
424
425 #hacky hacks to build the qmltypes
426
427-#should be already set by the qml_plugin.prf, but lets be safe
428-isEmpty(IMPORT_VERSION): error("Must set IMPORT_VERSION")
429-
430-load(resolve_target)
431-
432-qml1_target {
433- qmlplugindump = qml1plugindump
434- importpath.name = QML_IMPORT_PATH
435-} else {
436- qmlplugindump = qmlplugindump
437- importpath.name = QML2_IMPORT_PATH
438-}
439-
440-qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump)
441-importpath.value =
442-for(qmod, QTREPOS) {
443- qml1_target: \
444- qmod = $$qmod/imports
445- else: \
446- qmod = $$qmod/qml
447- exists($$qmod): importpath.value += $$shell_path($$qmod)
448-}
449-
450-#add our path, somehow its not added automatically
451-importpath.value += $$shell_path($$instbase)
452-importpath.value = $$unique(importpath.value)
453-
454-membackend.name = ALARM_BACKEND
455-membackend.value = memory
456-
457-qtAddToolEnv(QMLPLUGINDUMP, importpath)
458-qtAddToolEnv(QMLPLUGINDUMP, membackend)
459-
460-TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, )
461-
462-QMLTYPEFILE = $$instbase/$$TARGETPATH/plugins.qmltypes
463-autobld_qmltypes.target = $$QMLTYPEFILE
464-autobld_qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE
465-autobld_qmltypes.commands += && sed -i \'s?-1.-1\"?0.1\"?\' $$QMLTYPEFILE
466-autobld_qmltypes.commands += && sed -i \'s?exportMetaObjectRevisions: \\[-1\\]?exportMetaObjectRevisions: [0,0]?\' $$QMLTYPEFILE
467-autobld_qmltypes.depends = $$QMAKE_RESOLVED_TARGET
468-
469-autobld_install_qmltypes.files = $$QMLTYPEFILE
470-autobld_install_qmltypes.depends = $$QMLTYPEFILE
471-autobld_install_qmltypes.path = $$[QT_INSTALL_QML]/$$TARGETPATH
472-autobld_install_qmltypes.CONFIG += no_check_exist
473-
474-INSTALLS+=autobld_install_qmltypes
475-QMAKE_EXTRA_TARGETS += autobld_qmltypes
476+!build_with_qt{
477+ #should be already set by the qml_plugin.prf, but lets be safe
478+ isEmpty(IMPORT_VERSION): error("Must set IMPORT_VERSION")
479+
480+ load(resolve_target)
481+
482+ qml1_target {
483+ qmlplugindump = qml1plugindump
484+ importpath.name = QML_IMPORT_PATH
485+ } else {
486+ qmlplugindump = qmlplugindump
487+ importpath.name = QML2_IMPORT_PATH
488+ }
489+
490+ qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump)
491+ importpath.value =
492+ for(qmod, QTREPOS) {
493+ qml1_target: \
494+ qmod = $$qmod/imports
495+ else: \
496+ qmod = $$qmod/qml
497+ exists($$qmod): importpath.value += $$shell_path($$qmod)
498+ }
499+
500+ #add our path, somehow its not added automatically
501+ importpath.value += $$shell_path($$instbase)
502+ importpath.value = $$unique(importpath.value)
503+
504+ membackend.name = ALARM_BACKEND
505+ membackend.value = memory
506+
507+ qtAddToolEnv(QMLPLUGINDUMP, importpath)
508+ qtAddToolEnv(QMLPLUGINDUMP, membackend)
509+
510+ TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, )
511+
512+ QMLTYPEFILE = $$instbase/$$TARGETPATH/plugins.qmltypes
513+ autobld_qmltypes.target = $$QMLTYPEFILE
514+ autobld_qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE
515+ autobld_qmltypes.commands += && sed -i \'s?-1.-1\"?0.1\"?\' $$QMLTYPEFILE
516+ autobld_qmltypes.commands += && sed -i \'s?exportMetaObjectRevisions: \\[-1\\]?exportMetaObjectRevisions: [0,0]?\' $$QMLTYPEFILE
517+ autobld_qmltypes.depends = $$QMAKE_RESOLVED_TARGET
518+
519+ autobld_install_qmltypes.files = $$QMLTYPEFILE
520+ autobld_install_qmltypes.depends = $$QMLTYPEFILE
521+ autobld_install_qmltypes.path = $$[QT_INSTALL_QML]/$$TARGETPATH
522+ autobld_install_qmltypes.CONFIG += no_check_exist
523+
524+ INSTALLS+=autobld_install_qmltypes
525+ QMAKE_EXTRA_TARGETS += autobld_qmltypes
526+}
527
528 # when building against the system Qt we pick up the CXX_FLAGS for a release build
529 # reset them to the default debug build flags
530-force_independent: {
531+!build_with_qt: {
532 CONFIG(debug, debug|release) {
533 QMAKE_CFLAGS = $$QMAKE_CFLAGS_DEBUG
534 QMAKE_CXXFLAGS = $$QMAKE_CXXFLAGS_DEBUG
535
536=== modified file 'po/po.pro'
537--- po/po.pro 2014-12-02 09:00:30 +0000
538+++ po/po.pro 2015-09-08 04:09:38 +0000
539@@ -30,7 +30,7 @@
540 mo_file = $$replace(po_file,.po,.mo)
541 system(msgfmt $$po_file -o $$mo_file)
542 mo_name = $$replace(mo_file,.mo,)
543- mo_targetpath = $(INSTALL_ROOT)/usr/share/locale/$${mo_name}/LC_MESSAGES
544+ mo_targetpath = $(INSTALL_ROOT)$$[QT_INSTALL_PREFIX]/share/locale/$${mo_name}/LC_MESSAGES
545 mo_target = $${mo_targetpath}/ubuntu-ui-toolkit.mo
546 !isEmpty(install_mo_commands): install_mo_commands += &&
547 install_mo_commands += test -d $$mo_targetpath || mkdir -p $$mo_targetpath
548
549=== modified file 'src/Ubuntu/Components/1.1/Haptics.qml'
550--- src/Ubuntu/Components/1.1/Haptics.qml 2015-07-24 09:54:03 +0000
551+++ src/Ubuntu/Components/1.1/Haptics.qml 2015-09-08 04:09:38 +0000
552@@ -14,105 +14,14 @@
553 * along with this program. If not, see <http://www.gnu.org/licenses/>.
554 */
555
556-pragma Singleton
557 import QtQuick 2.4
558 import QtFeedback 5.0
559 import Ubuntu.Components 1.1
560
561-/*!
562- \qmltype Haptics
563- \inqmlmodule Ubuntu.Components 1.1
564- \ingroup ubuntu-services
565- \brief Singleton defining the haptics feedback used in components, where execution
566- of the feedback is controlled by the system settings.
567-
568- Supports global feedback as well as custom feedback. Global feedback can be
569- configured through its properties, and \l play function will play the default
570- configuration, or a custom one if parameter is given.
571-
572- Example of using Haptics:
573- \qml
574- import QtQuick 2.4
575- import Ubuntu.Components 1.2
576-
577- Item {
578- implicitWidth: units.gu(20)
579- implicitHeight: units.gu(5)
580-
581- Label {
582- text: "Press me"
583- anchors.fill: parent
584- horizontalAlignment: Text.AlignHCenter
585- verticalAlignment: Text.AlignVCenter
586- }
587- MouseArea {
588- anchors.fill: parent
589- onClicked: Haptics.play()
590- }
591- }
592- \endqml
593-
594- Custom effects can be played as follows:
595- \qml
596- import QtQuick 2.4
597- import Ubuntu.Components 1.2
598-
599- Item {
600- implicitWidth: units.gu(20)
601- implicitHeight: units.gu(5)
602-
603- Label {
604- text: "Press me"
605- anchors.fill: parent
606- horizontalAlignment: Text.AlignHCenter
607- verticalAlignment: Text.AlignVCenter
608- }
609- MouseArea {
610- anchors.fill: parent
611- onClicked: Haptics.play({duration: 25, attackIntensity: 0.7})
612- }
613- }
614- \endqml
615-
616- \note Though the \l effect property exposes \c start, \c stop and \c pause
617- functions, use those only if you want to have feedback independent on what the
618- system setting is.
619- */
620 Object {
621-
622- /*!
623- \qmlproperty bool enabled
624- \readonly
625- The property specifies whether the haptics feedback is enabled or not by the system.
626- */
627 readonly property alias enabled: vibra.otherVibrate
628-
629- /*!
630- \qmlproperty HapticsEffect effect
631- The property defines the settings of the haptics effect used by the component.
632- The default setting is a haptics effect with a duration of 10 milliseconds
633- with an intensity of 1.0, having fading time of 50 millisecods and fading
634- intensity 0.0, and attack time of 50 milliseconds and with an intensity of
635- 0.0.
636- */
637 property alias effect: effect
638
639- /*!
640- \qmlmethod play([customEffect])
641- The function plays the feedback with the configuration specified in \l effect
642- if no parameter is given. Custom effect can be played by specifying the effect
643- properties in a JSON object in \c customEffect.
644-
645- The function will exit unconditionaly if playing the effects is blocked by
646- system settings.
647-
648- The function will not stop any ongoing haptics effect played, if that one
649- was a default haptics effect. In case of custom effects, the previous effect
650- will be stopped, and settings will be restored before the new haptics will
651- be played. The custom settings properties (the ones which are required to
652- be different from the ones defined in the \l effect) must be specified in
653- the parameter in a JSON object.
654- */
655 function play(customEffect) {
656 if (!vibra.otherVibrate) {
657 return;
658
659=== removed file 'src/Ubuntu/Components/1.2/ActionItem.qml'
660--- src/Ubuntu/Components/1.2/ActionItem.qml 2015-04-30 08:32:44 +0000
661+++ src/Ubuntu/Components/1.2/ActionItem.qml 1970-01-01 00:00:00 +0000
662@@ -1,96 +0,0 @@
663-/*
664- * Copyright 2012 Canonical Ltd.
665- *
666- * This program is free software; you can redistribute it and/or modify
667- * it under the terms of the GNU Lesser General Public License as published by
668- * the Free Software Foundation; version 3.
669- *
670- * This program is distributed in the hope that it will be useful,
671- * but WITHOUT ANY WARRANTY; without even the implied warranty of
672- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
673- * GNU Lesser General Public License for more details.
674- *
675- * You should have received a copy of the GNU Lesser General Public License
676- * along with this program. If not, see <http://www.gnu.org/licenses/>.
677- */
678-
679-import QtQuick 2.4
680-import Ubuntu.Components 1.2
681-
682-/*!
683- \qmlabstract ActionItem
684- \inqmlmodule Ubuntu.Components 1.1
685- \ingroup ubuntu
686- \brief A visual representation of an Action. The API of ActionItem is a
687- copy of the API of \l Action, with additional properties to define
688- visual aspects of the ActionItem.
689-
690- If \l action is set, the values of the other properties will by default
691- be identical to the \l Action's property values. Setting the other properties
692- will override the properties copied from the \l Action.
693-
694- See \l ToolbarItems for examples of how to use \l ToolbarButton or other ActionItems
695- in a toolbar.
696-*/
697-StyledItem {
698- id: actionItem
699-
700- /*!
701- The \l Action associated with this ActionItem. If action is set,
702- the values of the Action properties are copied to the values of
703- the ActionItem properties.
704- */
705- property Action action: null
706-
707- visible: action ? action.visible : true
708- enabled: action ? action.enabled : true
709-
710- /*!
711- The title of the actionItem.
712- Default value: action.text
713- */
714- property string text: action ? action.text : ""
715-
716- /*!
717- The image associated with the actionItem.
718- Default value: action.iconSource.
719-
720- This is the URL of any image file
721- If both iconSource and iconName are defined, iconName will be ignored.
722- */
723- property url iconSource: action ? action.iconSource : (iconName ? "image://theme/" + iconName : "")
724-
725- /*!
726- The icon associated with the actionItem in the suru icon theme.
727- Default value: action.iconName.
728-
729- \note The complete list of icons available in Ubuntu is not published yet.
730- For now please refer to the folders where the icon themes are installed:
731- \list
732- \li Ubuntu Touch: \l file:/usr/share/icons/suru
733- \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark
734- \endlist
735- These 2 separate icon themes will be merged soon.
736-
737- If both iconSource and iconName are defined, iconName will be ignored.
738- */
739- property string iconName: action ? action.iconName : ""
740-
741- /*!
742- Called when the actionItem is triggered.
743- */
744- signal triggered(var value)
745-
746- /*!
747- If \l action is set, this will trigger it.
748- */
749- onTriggered: if (action) action.trigger(value)
750-
751- /*!
752- Trigger this action item if it is enabled.
753- */
754- function trigger(value) {
755- var passingValue = value ? value : null
756- if (actionItem.enabled) actionItem.triggered(passingValue);
757- }
758-}
759
760=== modified file 'src/Ubuntu/Components/1.2/TextField.qml'
761--- src/Ubuntu/Components/1.2/TextField.qml 2015-05-01 19:38:57 +0000
762+++ src/Ubuntu/Components/1.2/TextField.qml 2015-09-08 04:09:38 +0000
763@@ -99,7 +99,7 @@
764 \note During text selection all interactive parent Flickables are turned off.
765 */
766
767-ActionItem {
768+Ubuntu.ActionItem {
769 id: control
770
771 implicitWidth: units.gu(25)
772
773=== modified file 'src/Ubuntu/Components/1.2/TextInputPopover.qml'
774--- src/Ubuntu/Components/1.2/TextInputPopover.qml 2015-07-02 23:33:22 +0000
775+++ src/Ubuntu/Components/1.2/TextInputPopover.qml 2015-09-08 04:09:38 +0000
776@@ -88,6 +88,7 @@
777 action.text so we can get the proper button by text, action being not
778 accessible. https://bugs.launchpad.net/autopilot/+bug/1334599
779 */
780+ // FIXME: AbstractButton has text property, which is getting the action.text, so no need to override!
781 property string text: action.text
782 width: Math.max(units.gu(5), implicitWidth) + units.gu(2)
783 height: units.gu(6)
784
785=== modified file 'src/Ubuntu/Components/1.2/ToolbarButton.qml'
786--- src/Ubuntu/Components/1.2/ToolbarButton.qml 2015-04-30 08:32:44 +0000
787+++ src/Ubuntu/Components/1.2/ToolbarButton.qml 2015-09-08 04:09:38 +0000
788@@ -15,6 +15,7 @@
789 */
790
791 import QtQuick 2.4
792+import Ubuntu.Components 1.2
793
794 /*!
795 \qmltype ToolbarButton
796
797=== removed file 'src/Ubuntu/Components/1.3/AbstractButton.qml'
798--- src/Ubuntu/Components/1.3/AbstractButton.qml 2015-04-25 08:54:58 +0000
799+++ src/Ubuntu/Components/1.3/AbstractButton.qml 1970-01-01 00:00:00 +0000
800@@ -1,109 +0,0 @@
801-/*
802- * Copyright 2012 Canonical Ltd.
803- *
804- * This program is free software; you can redistribute it and/or modify
805- * it under the terms of the GNU Lesser General Public License as published by
806- * the Free Software Foundation; version 3.
807- *
808- * This program is distributed in the hope that it will be useful,
809- * but WITHOUT ANY WARRANTY; without even the implied warranty of
810- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
811- * GNU Lesser General Public License for more details.
812- *
813- * You should have received a copy of the GNU Lesser General Public License
814- * along with this program. If not, see <http://www.gnu.org/licenses/>.
815- */
816-
817-import QtQuick 2.4
818-import Ubuntu.Components 1.3
819-
820-/*!
821- \qmlabstract AbstractButton
822- \inqmlmodule Ubuntu.Components 1.1
823- \ingroup ubuntu
824- \brief The AbstractButton class defines the behavior of the button.
825-
826- This class defines the behavior of the button: it defines the MouseArea
827- and the states.
828- All components deriving from this class support haptic feedback out of the box.
829-*/
830-ActionItem {
831- id: button
832-
833- /*!
834- If an action is specified, the button's clicked signal will trigger the action.
835- Subclasses of AbstractButton can use other properties of action (for example
836- the text and iconName).
837- \qmlproperty Action action
838- */
839-
840- /*!
841- This handler is called when there is a mouse click on the button
842- and the button is not disabled. If \b action is defined,
843- the action will be triggered.
844- */
845- signal clicked()
846-
847- /*!
848- If a button is clicked, its triggered() signal will automatically be called.
849- */
850- onClicked: button.trigger()
851-
852- Keys.onEnterPressed: clicked()
853- Keys.onReturnPressed: clicked()
854-
855- /*!
856- This handler is called when there is a long press.
857- */
858- signal pressAndHold()
859-
860- /*!
861- True if the user presses a mouse button in the button's mouse area.
862- */
863- property bool pressed: mouseArea.pressed
864-
865- /*!
866- True if the mouse cursor hovers over the button's mouse area.
867- */
868- property bool hovered: __acceptEvents && mouseArea.containsMouse
869-
870- /*!
871- \internal
872- Disable or enable signal emition by default.
873- Some classes want to emit the signal by themselves (ListItem.Standard)
874- */
875- property bool __acceptEvents: true
876-
877- /*!
878- \internal
879- To get the properties of the mouse area in subclasses.
880- */
881- property alias __mouseArea: mouseArea
882-
883- activeFocusOnPress: true
884-
885- MouseArea {
886- id: mouseArea
887- anchors.fill: parent
888- // if mouseArea is given a new value, disable defaultMouseArea
889- // as it might occlude the newly assigned mouse area.
890- hoverEnabled: true
891-
892- // invoke Haptics singleton earlier than we press the button,
893- // so we give some time for the singleton to sync settings with the service
894- property bool hapticsEnabled: Haptics.enabled
895-
896- onClicked: {
897- if (button.__acceptEvents) {
898- // FIXME (Vivid) call this in the style rather than from AbstractButton
899- Haptics.play();
900- button.clicked()
901- }
902- }
903- onPressAndHold: {
904- if (button.__acceptEvents) {
905- button.pressAndHold()
906- }
907- }
908- }
909-}
910
911=== removed file 'src/Ubuntu/Components/1.3/ActionItem.qml'
912--- src/Ubuntu/Components/1.3/ActionItem.qml 2015-04-25 08:54:58 +0000
913+++ src/Ubuntu/Components/1.3/ActionItem.qml 1970-01-01 00:00:00 +0000
914@@ -1,96 +0,0 @@
915-/*
916- * Copyright 2012 Canonical Ltd.
917- *
918- * This program is free software; you can redistribute it and/or modify
919- * it under the terms of the GNU Lesser General Public License as published by
920- * the Free Software Foundation; version 3.
921- *
922- * This program is distributed in the hope that it will be useful,
923- * but WITHOUT ANY WARRANTY; without even the implied warranty of
924- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
925- * GNU Lesser General Public License for more details.
926- *
927- * You should have received a copy of the GNU Lesser General Public License
928- * along with this program. If not, see <http://www.gnu.org/licenses/>.
929- */
930-
931-import QtQuick 2.4
932-import Ubuntu.Components 1.3
933-
934-/*!
935- \qmlabstract ActionItem
936- \inqmlmodule Ubuntu.Components 1.1
937- \ingroup ubuntu
938- \brief A visual representation of an Action. The API of ActionItem is a
939- copy of the API of \l Action, with additional properties to define
940- visual aspects of the ActionItem.
941-
942- If \l action is set, the values of the other properties will by default
943- be identical to the \l Action's property values. Setting the other properties
944- will override the properties copied from the \l Action.
945-
946- See \l ToolbarItems for examples of how to use \l ToolbarButton or other ActionItems
947- in a toolbar.
948-*/
949-StyledItem {
950- id: actionItem
951-
952- /*!
953- The \l Action associated with this ActionItem. If action is set,
954- the values of the Action properties are copied to the values of
955- the ActionItem properties.
956- */
957- property Action action: null
958-
959- visible: action ? action.visible : true
960- enabled: action ? action.enabled : true
961-
962- /*!
963- The title of the actionItem.
964- Default value: action.text
965- */
966- property string text: action ? action.text : ""
967-
968- /*!
969- The image associated with the actionItem.
970- Default value: action.iconSource.
971-
972- This is the URL of any image file
973- If both iconSource and iconName are defined, iconName will be ignored.
974- */
975- property url iconSource: action ? action.iconSource : (iconName ? "image://theme/" + iconName : "")
976-
977- /*!
978- The icon associated with the actionItem in the suru icon theme.
979- Default value: action.iconName.
980-
981- \note The complete list of icons available in Ubuntu is not published yet.
982- For now please refer to the folders where the icon themes are installed:
983- \list
984- \li Ubuntu Touch: \l file:/usr/share/icons/suru
985- \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark
986- \endlist
987- These 2 separate icon themes will be merged soon.
988-
989- If both iconSource and iconName are defined, iconName will be ignored.
990- */
991- property string iconName: action ? action.iconName : ""
992-
993- /*!
994- Called when the actionItem is triggered.
995- */
996- signal triggered(var value)
997-
998- /*!
999- If \l action is set, this will trigger it.
1000- */
1001- onTriggered: if (action) action.trigger(value)
1002-
1003- /*!
1004- Trigger this action item if it is enabled.
1005- */
1006- function trigger(value) {
1007- var passingValue = value ? value : null
1008- if (actionItem.enabled) actionItem.triggered(passingValue);
1009- }
1010-}
1011
1012=== modified file 'src/Ubuntu/Components/1.3/AdaptivePageLayout.qml'
1013--- src/Ubuntu/Components/1.3/AdaptivePageLayout.qml 2015-07-28 15:04:07 +0000
1014+++ src/Ubuntu/Components/1.3/AdaptivePageLayout.qml 2015-09-08 04:09:38 +0000
1015@@ -83,10 +83,85 @@
1016 }
1017 \endqml
1018
1019+ \note Observe the use of the \c Page::pageStack property in the example above.
1020+ The same property is used to share the AdaptivePageLayout instance the Page is
1021+ used in, therefore the same page can be used in a PageStack or in an AdaptivePageLayout.
1022+ However implementations must make sure the desired PageStack or AdaptivePageLayout
1023+ function exists in the instance before using it.
1024+
1025 AdaptivePageLayout supports adaptive column handling. When the number of columns changes at
1026 runtime the pages are automatically rearranged.
1027
1028- \sa PageStack
1029+ By default the component splits the layout in two columns when the width of the
1030+ layout exceeds 80 grid units. The first column is sized to 40 grid unit width and
1031+ the second one to fill the rest of the remaining space. When the 80 grid unit breakpoint
1032+ is reached, the component will switch from one column to two, and vice versa.
1033+ These defaults can be overridden through the \l layouts property by defining the
1034+ possible layouts, their column sizing and the breakpoints when the layouts should
1035+ be activated. PageColumn configurations must appear in the same order (from left
1036+ to right) as the columns appear in the layout. If none of the layouts condition
1037+ is met, a one column layout will be used.
1038+
1039+ \qml
1040+ import QtQuick 2.4
1041+ import Ubuntu.Components 1.3
1042+
1043+ MainView {
1044+ width: units.gu(100)
1045+ height: units.gu(60)
1046+
1047+ AdaptivePageLayout {
1048+ anchors.fill: parent
1049+ primaryPage: page1
1050+ layouts: PageColumnsLayout {
1051+ when: width > units.gu(80)
1052+ // column #0
1053+ PageColumn {
1054+ minimumWidth: units.gu(30)
1055+ maximumWidth: units.gu(60)
1056+ preferredWidth: units.gu(40)
1057+ }
1058+ // column #1
1059+ PageColumn {
1060+ fillWidth: true
1061+ }
1062+ }
1063+
1064+ Page {
1065+ id: page1
1066+ title: "Main page"
1067+ Column {
1068+ Button {
1069+ text: "Add Page2 above " + page1.title
1070+ onClicked: page1.pageStack.addPageToCurrentColumn(page1, page2)
1071+ }
1072+ Button {
1073+ text: "Add Page3 next to " + page1.title
1074+ onClicked: page1.pageStack.addPageToNextColumn(page1, page3)
1075+ }
1076+ }
1077+ }
1078+ Page {
1079+ id: page2
1080+ title: "Page #2"
1081+ }
1082+ Page {
1083+ id: page3
1084+ title: "Page #3"
1085+ }
1086+ }
1087+ }
1088+ \endqml
1089+
1090+ A column is considered to be resizable if the \l PageColumn::minimumWidth and
1091+ \l PageColumn::maximumWidth configuration differs. This implies that if a column
1092+ is not meant to be resized, it should have \l PageColumn::minimumWidth and
1093+ \l PageColumn::maximumWidth set to the same value. In the example above, the
1094+ first column can be resized to a minimum of 30, and a maximum of 60 grid units,
1095+ and the preferred width is set to 40 grid units. This width is set every time
1096+ the layout is activated.
1097+
1098+ \sa PageStack, PageColumnsLayout, PageColumn
1099 */
1100
1101 PageTreeNode {
1102@@ -113,12 +188,86 @@
1103 property Page primaryPage
1104
1105 /*!
1106- \qmlmethod Item addPageToCurrentColumn(Item sourcePage, var page[, var properties])
1107+ \qmlproperty int columns
1108+ \readonly
1109+ The property holds the number of columns shown in the layout.
1110+ */
1111+ readonly property alias columns: d.columns
1112+
1113+ /*!
1114+ The property holds the different layout configurations overriding the default
1115+ configurations. Defaults to an empty list.
1116+ \sa PageColumnsLayout
1117+ */
1118+ property list<PageColumnsLayout> layouts
1119+
1120+ /*!
1121+ \qmlmethod object addPageToCurrentColumn(Item sourcePage, var page[, var properties])
1122 Adds a \c page to the column the \c sourcePage resides in and removes all pages
1123 from the higher columns. \c page can be a Component or a file.
1124- \c properties is a JSON object containing properties
1125- to be set when page is created. \c sourcePage must be active. Returns the
1126- instance of the page created.
1127+ \c properties is a JSON object containing properties to be set when page
1128+ is created. \c sourcePage must be active.
1129+
1130+ The function creates the new page asynchronously if the new \c page to be
1131+ added is a Component or a QML document. In this case the function returns
1132+ an incubator which can be used to track the page creation.For more about
1133+ incubation in QML and creating components asynchronously, see
1134+ \l {http://doc.qt.io/qt-5/qml-qtqml-component.html#incubateObject-method}
1135+ {Component.incubateObject()}.
1136+ The following example removes an element from the list model whenever the
1137+ page opened in the second column is closed. Note, the example must be run
1138+ on desktop or on a device with at least 90 grid units screen width.
1139+ \qml
1140+ import QtQuick 2.4
1141+ import Ubuntu.Components 1.3
1142+
1143+ MainView {
1144+ width: units.gu(90)
1145+ height: units.gu(70)
1146+
1147+ Component {
1148+ id: page2Component
1149+ Page {
1150+ title: "Second Page"
1151+ Button {
1152+ text: "Close me"
1153+ onClicked: pageStack.removePages(pageStack.primaryPage);
1154+ }
1155+ }
1156+ }
1157+
1158+ AdaptivePageLayout {
1159+ id: pageLayout
1160+ anchors.fill: parent
1161+ primaryPage: Page {
1162+ title: "Primary Page"
1163+ ListView {
1164+ id: listView
1165+ anchors.fill: parent
1166+ model: 10
1167+ delegate: ListItem {
1168+ Label { text: modelData }
1169+ onClicked: {
1170+ var incubator = pageLayout.addPageToNextColumn(pageLayout.primaryPage, page2Component);
1171+ if (incubator && incubator.status == Component.Loading) {
1172+ incubator.onStatusChanged = function(status) {
1173+ if (status == Component.Ready) {
1174+ // connect page's destruction to decrement model
1175+ incubator.object.Component.destruction.connect(function() {
1176+ listView.model--;
1177+ });
1178+ }
1179+ }
1180+ }
1181+ }
1182+ }
1183+ }
1184+ }
1185+ }
1186+ }
1187+ \endqml
1188+
1189+ \sa {http://doc.qt.io/qt-5/qml-qtqml-component.html#incubateObject-method}{Component.incubateObject}
1190 */
1191 function addPageToCurrentColumn(sourcePage, page, properties) {
1192 var nextColumn = d.columnForPage(sourcePage) + 1;
1193@@ -138,6 +287,7 @@
1194 holds \c sourcePage) and all following columns, and then add \c page to the next column.
1195 If \c sourcePage is located in the
1196 rightmost column, the new page will be pushed to the same column as \c sourcePage.
1197+ The return value is the same as in \l addPageToCurrentColumn case.
1198 */
1199 function addPageToNextColumn(sourcePage, page, properties) {
1200 var nextColumn = d.columnForPage(sourcePage) + 1;
1201@@ -168,7 +318,12 @@
1202 */
1203
1204 Component.onCompleted: {
1205- d.relayout();
1206+ // check layout configuration
1207+ if (layouts.length > 0) {
1208+ d.prepareLayouts();
1209+ } else {
1210+ d.relayout();
1211+ }
1212 d.completed = true;
1213 if (primaryPage) {
1214 var wrapper = d.createWrapper(primaryPage);
1215@@ -183,6 +338,13 @@
1216 return;
1217 }
1218 }
1219+ onLayoutsChanged: {
1220+ if (d.completed) {
1221+ // only deal with this if the layouts array changes after completion
1222+ // to avoid unnecessary rendering
1223+ d.prepareLayouts();
1224+ }
1225+ }
1226
1227 QtObject {
1228 id: d
1229@@ -190,7 +352,12 @@
1230 property bool completed: false
1231 property var tree: new Tree.Tree()
1232
1233- property int columns: layout.width >= units.gu(80) ? 2 : 1
1234+ property int columns: !layout.layouts.length ?
1235+ (layout.width >= units.gu(80) ? 2 : 1) :
1236+ (activeLayout ? activeLayout.data.length : 1)
1237+ property PageColumnsLayout activeLayout: null
1238+ property list<PageColumnsLayout> prevLayouts
1239+
1240 /*! internal */
1241 onColumnsChanged: {
1242 if (columns <= 0) {
1243@@ -201,11 +368,10 @@
1244 }
1245 property real defaultColumnWidth: units.gu(40)
1246 onDefaultColumnWidthChanged: body.applyMetrics()
1247- property list<ColumnMetrics> columnMetrics
1248
1249 function createWrapper(page, properties) {
1250 var wrapperComponent = Qt.createComponent("PageWrapper.qml");
1251- var wrapperObject = wrapperComponent.createObject(hiddenPages);
1252+ var wrapperObject = wrapperComponent.createObject(hiddenPages, {synchronous: false});
1253 wrapperObject.pageStack = layout;
1254 wrapperObject.properties = properties;
1255 // set reference last because it will trigger creation of the object
1256@@ -221,7 +387,14 @@
1257 // replace page holder's child
1258 var holder = body.children[targetColumn];
1259 holder.detachCurrentPage();
1260- holder.attachPage(pageWrapper)
1261+ if ((pageWrapper.incubator && pageWrapper.incubator.status == Component.Ready) || pageWrapper.object) {
1262+ holder.attachPage(pageWrapper);
1263+ } else {
1264+ // asynchronous, connect to page load completion and attach when page is available
1265+ pageWrapper.pageLoaded.connect(function () {
1266+ holder.attachPage(pageWrapper);
1267+ });
1268+ }
1269 }
1270
1271 function getWrapper(page) {
1272@@ -279,7 +452,7 @@
1273 newWrapper.parentPage = sourcePage;
1274 newWrapper.column = column;
1275 d.addWrappedPage(newWrapper);
1276- return newWrapper.object;
1277+ return newWrapper.incubator;
1278 }
1279
1280 // update the page for the specified column
1281@@ -301,6 +474,33 @@
1282 }
1283 }
1284
1285+ // prepares layout management, listens on layout condition changes and performs re-layouting
1286+ function prepareLayouts() {
1287+ // disconnect from the previous layouts
1288+ for (var i = 0; i < prevLayouts.length; i++) {
1289+ prevLayouts[i].whenChanged.disconnect(updateLayout);
1290+ }
1291+ prevLayouts = layouts;
1292+ for (var i = 0; i < layouts.length; i++) {
1293+ layouts[i].whenChanged.connect(updateLayout);
1294+ }
1295+ // first time evaluation
1296+ updateLayout();
1297+ }
1298+
1299+ // function called when one of the layout condition is satisfied
1300+ function updateLayout() {
1301+ var newLayout = null;
1302+ for (var i = 0; i < layouts.length; i++) {
1303+ // get the first affirmative condition
1304+ if (layouts[i].when) {
1305+ newLayout = layouts[i];
1306+ break;
1307+ }
1308+ }
1309+ d.activeLayout = newLayout;
1310+ }
1311+
1312 // relayouts when column count changes
1313 function relayout() {
1314 if (body.children.length == d.columns) return;
1315@@ -357,8 +557,8 @@
1316 // default metrics
1317 Component {
1318 id: defaultMetrics
1319- ColumnMetrics {
1320- fillWidth: column == d.columns
1321+ PageColumn {
1322+ fillWidth: __column == d.columns
1323 minimumWidth: d.defaultColumnWidth
1324 }
1325 }
1326@@ -376,13 +576,12 @@
1327 property PageWrapper pageWrapper
1328 property int column
1329 property alias config: subHeader.config
1330- property ColumnMetrics metrics: setDefaultMetrics()
1331+ property PageColumn metrics: getDefaultMetrics()
1332+ readonly property real dividerThickness: units.dp(1)
1333
1334 Layout.fillWidth: metrics.fillWidth
1335 Layout.fillHeight: true
1336- Layout.preferredWidth: metrics.maximumWidth > 0 ?
1337- MathUtils.clamp(d.defaultColumnWidth, metrics.minimumWidth, metrics.maximumWidth) :
1338- d.defaultColumnWidth
1339+ Layout.preferredWidth: MathUtils.clamp(metrics.preferredWidth, metrics.minimumWidth, metrics.maximumWidth)
1340 Layout.minimumWidth: metrics.minimumWidth
1341 Layout.maximumWidth: metrics.maximumWidth
1342
1343@@ -396,7 +595,7 @@
1344 bottom: parent.bottom
1345 left: parent.left
1346 right: parent.right
1347- rightMargin: verticalDivider.width
1348+ rightMargin: dividerThickness
1349 }
1350 // we need to clip because the header does not have a background
1351 clip: true
1352@@ -412,7 +611,7 @@
1353 }
1354 height: body.headerHeight
1355
1356- styleName: config ? "PageHeadStyle" : ""
1357+ styleName: "PageHeadStyle"
1358 theme.version: Ubuntu.toolkitVersion
1359 objectName: "Header" + column
1360
1361@@ -457,9 +656,52 @@
1362 top: parent.top
1363 bottom: parent.bottom
1364 right: parent.right
1365+ rightMargin: dividerThickness
1366 }
1367 width: (column == (d.columns - 1)) || !pageWrapper ? 0 : units.dp(1)
1368- color: subHeader.dividerColor
1369+ color: theme.palette.selected.background
1370+ MouseArea {
1371+ id: resizerSensing
1372+ objectName: "Divider"
1373+ enabled: verticalDivider.width > 0
1374+ anchors {
1375+ fill: parent
1376+ leftMargin: enabled ? -units.gu(1) : 0
1377+ rightMargin: enabled ? -units.gu(1) : 0
1378+ }
1379+ cursorShape: Qt.SizeHorCursor
1380+ drag {
1381+ axis: Drag.XAxis
1382+ target: resizer
1383+ smoothed: false
1384+ minimumX: holder.Layout.minimumWidth
1385+ maximumX: holder.Layout.maximumWidth
1386+ }
1387+ onPressed: resizer.x = holder.Layout.preferredWidth
1388+ }
1389+ states: State {
1390+ name: "active"
1391+ when: resizerSensing.pressed
1392+ PropertyChanges {
1393+ target: verticalDivider
1394+ color: Qt.darker(theme.palette.normal.background, 1.5)
1395+ }
1396+ }
1397+ transitions: Transition {
1398+ from: ""
1399+ to: "*"
1400+ reversible: true
1401+ ColorAnimation {
1402+ target: verticalDivider
1403+ property: "color"
1404+ duration: UbuntuAnimation.SlowDuration
1405+ }
1406+ }
1407+ }
1408+ Item {
1409+ id: resizer
1410+ height: parent.height
1411+ onXChanged: holder.Layout.preferredWidth = x
1412 }
1413
1414 function attachPage(page) {
1415@@ -488,9 +730,9 @@
1416 return wrapper;
1417 }
1418
1419- function setDefaultMetrics() {
1420+ function getDefaultMetrics() {
1421 var result = defaultMetrics.createObject(holder);
1422- result.column = Qt.binding(function() { return holder.column + 1; });
1423+ result.__column = Qt.binding(function() { return holder.column + 1; });
1424 return result;
1425 }
1426 }
1427@@ -545,15 +787,9 @@
1428 for (var i = 0; i < children.length; i++) {
1429 var holder = children[i];
1430 // search for the column metrics
1431- var metrics = null;
1432- for (var j = 0; j < d.columnMetrics.length; j++) {
1433- if (d.columnMetrics[j].column == (i + 1)) {
1434- metrics = d.columnMetrics[j];
1435- break;
1436- }
1437- }
1438+ var metrics = d.activeLayout ? d.activeLayout.data[i] : null;
1439 if (!metrics) {
1440- metrics = holder.setDefaultMetrics();
1441+ metrics = holder.getDefaultMetrics();
1442 }
1443 holder.metrics = metrics;
1444 updateHeaderHeight(0);
1445
1446=== modified file 'src/Ubuntu/Components/1.3/AppHeader.qml'
1447--- src/Ubuntu/Components/1.3/AppHeader.qml 2015-08-03 15:02:42 +0000
1448+++ src/Ubuntu/Components/1.3/AppHeader.qml 2015-09-08 04:09:38 +0000
1449@@ -184,11 +184,6 @@
1450 }
1451
1452 /*!
1453- Set by \l MainView
1454- */
1455- property bool useDeprecatedToolbar: true
1456-
1457- /*!
1458 Configuration of the header.
1459 FIXME: Must be of type PageHeadConfiguration. Setting that as the property type
1460 however will use the latest version (1.3) and a Page that uses an older
1461@@ -355,5 +350,5 @@
1462 }
1463
1464 theme.version: Components.Ubuntu.toolkitVersion
1465- styleName: header.useDeprecatedToolbar ? "HeaderStyle" : "PageHeadStyle"
1466+ styleName: "PageHeadStyle"
1467 }
1468
1469=== modified file 'src/Ubuntu/Components/1.3/Button.qml'
1470--- src/Ubuntu/Components/1.3/Button.qml 2015-05-26 15:05:46 +0000
1471+++ src/Ubuntu/Components/1.3/Button.qml 2015-09-08 04:09:38 +0000
1472@@ -105,7 +105,7 @@
1473 /*!
1474 The font used for the button's text.
1475 */
1476- property font font: __styleInstance ? __styleInstance.defaultFont : Qt.font({family: "Ubuntu", pixelSize: FontUtils.sizeToPixels("medium")})
1477+ property font font: __styleInstance.defaultFont
1478
1479 /*!
1480 The position of the icon relative to the text. Options
1481
1482=== modified file 'src/Ubuntu/Components/1.3/ComboButton.qml'
1483--- src/Ubuntu/Components/1.3/ComboButton.qml 2015-05-21 10:50:35 +0000
1484+++ src/Ubuntu/Components/1.3/ComboButton.qml 2015-09-08 04:09:38 +0000
1485@@ -15,6 +15,7 @@
1486 */
1487
1488 import QtQuick 2.4
1489+import Ubuntu.Components 1.3
1490 import Ubuntu.Components.Popups 1.3
1491
1492 /*!
1493
1494=== removed file 'src/Ubuntu/Components/1.3/Header.qml'
1495--- src/Ubuntu/Components/1.3/Header.qml 2015-04-25 08:54:58 +0000
1496+++ src/Ubuntu/Components/1.3/Header.qml 1970-01-01 00:00:00 +0000
1497@@ -1,39 +0,0 @@
1498-/*
1499- * Copyright 2014 Canonical Ltd.
1500- *
1501- * This program is free software; you can redistribute it and/or modify
1502- * it under the terms of the GNU Lesser General Public License as published by
1503- * the Free Software Foundation; version 3.
1504- *
1505- * This program is distributed in the hope that it will be useful,
1506- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1507- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1508- * GNU Lesser General Public License for more details.
1509- *
1510- * You should have received a copy of the GNU Lesser General Public License
1511- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1512- */
1513-
1514-import QtQuick 2.4
1515-
1516-/*!
1517- \qmltype Header
1518- \internal
1519- \deprecated
1520-*/
1521-AppHeader {
1522-
1523- /*!
1524- \internal
1525- We need this property so QML exposes this class as Header instead of
1526- AppHeader. This way autopilot can select the deprecated header.
1527- */
1528- property string _for_autopilot
1529-
1530- Component.onCompleted: {
1531- print("WARNING: Header is an internal component of Ubuntu.Components and" +
1532- "its API may change or be removed at any moment." +
1533- "Please use MainView and Page instead."
1534- );
1535- }
1536-}
1537
1538=== modified file 'src/Ubuntu/Components/1.3/MainView.qml'
1539--- src/Ubuntu/Components/1.3/MainView.qml 2015-08-10 15:35:04 +0000
1540+++ src/Ubuntu/Components/1.3/MainView.qml 2015-09-08 04:09:38 +0000
1541@@ -191,9 +191,6 @@
1542 window.title = headerItem.title
1543 }
1544 }
1545-
1546- // Use of the deprecated toolbar is no longer supported in MainView 1.2.
1547- useDeprecatedToolbar: false
1548 }
1549
1550 Connections {
1551
1552=== modified file 'src/Ubuntu/Components/1.3/MainViewBase.qml'
1553--- src/Ubuntu/Components/1.3/MainViewBase.qml 2015-08-06 22:32:02 +0000
1554+++ src/Ubuntu/Components/1.3/MainViewBase.qml 2015-09-08 04:09:38 +0000
1555@@ -28,6 +28,8 @@
1556 */
1557 PageTreeNode {
1558 id: mainView
1559+ styleName: "MainViewStyle"
1560+
1561 /*!
1562 The property holds the application's name, which must be the same as the
1563 desktop file's name.
1564@@ -53,7 +55,7 @@
1565
1566 \sa backgroundColor, footerColor
1567 */
1568- property alias headerColor: background.headerColor
1569+ property color headerColor: backgroundColor
1570
1571 /*!
1572 \qmlproperty color MainView::backgroundColor
1573@@ -80,7 +82,7 @@
1574
1575 \sa footerColor, headerColor
1576 */
1577- property alias backgroundColor: background.backgroundColor
1578+ property color backgroundColor: theme.palette.normal.background
1579
1580 /*!
1581 \qmlproperty color MainView::footerColor
1582@@ -88,22 +90,12 @@
1583
1584 \sa backgroundColor, headerColor
1585 */
1586- property alias footerColor: background.footerColor
1587-
1588- // FIXME: Make sure that the theming is only in the background, and the style
1589- // should not occlude contents of the MainView. When making changes here, make
1590- // sure that bug https://bugs.launchpad.net/manhattan/+bug/1124076 does not come back.
1591- Toolkit.StyledItem {
1592- id: background
1593- anchors.fill: parent
1594- // theme is inherited from PageTreeNode, no need to update versioning
1595- styleName: "MainViewStyle"
1596-
1597- // FIXME: Define the colors in MainViewStyle and get rid of the properties
1598- // in MainViewBase.
1599- property color headerColor: backgroundColor
1600- property color backgroundColor: theme.palette.normal.background
1601- property color footerColor: backgroundColor
1602+ property color footerColor: backgroundColor
1603+
1604+ Toolkit.Object {
1605+ id: autoTheme
1606+ // FIXME: Define the background colors in MainViewStyle and get rid of the properties
1607+ // in MainViewBase. That removes the need for auto-theming.
1608
1609 /*
1610 As we don't know the order the property bindings and onXXXChanged signals are evaluated
1611@@ -113,18 +105,23 @@
1612 Qt bug: https://bugreports.qt-project.org/browse/QTBUG-11712
1613 */
1614
1615- onBackgroundColorChanged: {
1616- if (backgroundColor != theme.palette.normal.background) {
1617- // custom color, proceed with auto-theming
1618- autoThemeName = (ColorUtils.luminance(backgroundColor) >= 0.85) ?
1619- "Ambiance" : "SuruDark";
1620+ Connections {
1621+ target: mainView
1622+
1623+ onBackgroundColorChanged: {
1624+ if (mainView.backgroundColor != theme.palette.normal.background) {
1625+ // custom color, proceed with auto-theming
1626+ autoTheme.themeName = (ColorUtils.luminance(backgroundColor) >= 0.85) ?
1627+ "Ambiance" : "SuruDark";
1628+ }
1629 }
1630 }
1631- property string autoThemeName
1632- onAutoThemeNameChanged: {
1633+
1634+ property string themeName
1635+ onThemeNameChanged: {
1636 // only change the theme if the current one is a system one.
1637- if (autoThemeName !== "" && (theme.name.search("Ubuntu.Components.Themes") == 0)) {
1638- mainView.theme.name = "Ubuntu.Components.Themes.%1".arg(autoThemeName);
1639+ if (themeName !== "" && (theme.name.search("Ubuntu.Components.Themes") == 0)) {
1640+ mainView.theme.name = "Ubuntu.Components.Themes.%1".arg(themeName);
1641 }
1642 }
1643 }
1644
1645=== renamed file 'src/Ubuntu/Components/1.3/ColumnMetrics.qml' => 'src/Ubuntu/Components/1.3/PageColumn.qml'
1646--- src/Ubuntu/Components/1.3/ColumnMetrics.qml 2015-06-24 16:16:13 +0000
1647+++ src/Ubuntu/Components/1.3/PageColumn.qml 2015-09-08 04:09:38 +0000
1648@@ -17,37 +17,42 @@
1649 import QtQuick 2.4
1650
1651 /*!
1652- \qmltype ColumnMetrics
1653+ \qmltype PageColumn
1654 \inqmlmodule Ubuntu.Components 1.3
1655 \since Ubuntu.Components 1.3
1656 \ingroup ubuntu
1657- \brief Component configuring the metrics of a column in MultiColumnView.
1658- \internal
1659+ \brief Component configuring the metrics of a column in AdaptivePageLayout.
1660
1661 */
1662 QtObject {
1663 /*!
1664 1-based value identifying the column the metrics to be applied to.
1665+ \internal
1666 */
1667- property int column
1668+ property int __column
1669
1670 /*!
1671 Specifies whether the width of the column should fill the available space
1672- of the MultiColumnView column or not. Defaults to \a false.
1673+ of the AdaptivePageLayout column or not. Defaults to \a false.
1674 */
1675 property bool fillWidth: false
1676
1677 /*!
1678- Specifies the minimum width of the column. If the value is greater than
1679- \b MultiColumnView::defaultColumnWidth, the value will be set as width for
1680- the column.
1681+ Specifies the minimum width of the column. Defaults to 0.
1682 */
1683 property real minimumWidth: 0
1684
1685 /*!
1686- Specifies the maximum width of the column. If the value is smaller than
1687- \b MultiColumnView::defaultColumnWidth, the value will be set as width for
1688- the column. A maximum value of 0 will be ignored.
1689+ Specifies the maximum width of the column. A maximum value of 0 will be ignored.
1690+ Defaults to the maximum positive value.
1691 */
1692 property real maximumWidth: Number.POSITIVE_INFINITY
1693+
1694+ /*!
1695+ Specifies the preferred width of the column when the layout is initialized.
1696+ Defaults to 0. AdaptivePageLayout clamps the given value between \l minimumWidth
1697+ and \l maximumWidth. The value must be set if the \l fillWidth and \l minimumWidth
1698+ are not set.
1699+ */
1700+ property real preferredWidth: 0
1701 }
1702
1703=== added file 'src/Ubuntu/Components/1.3/PageColumnsLayout.qml'
1704--- src/Ubuntu/Components/1.3/PageColumnsLayout.qml 1970-01-01 00:00:00 +0000
1705+++ src/Ubuntu/Components/1.3/PageColumnsLayout.qml 2015-09-08 04:09:38 +0000
1706@@ -0,0 +1,115 @@
1707+/*
1708+ * Copyright 2015 Canonical Ltd.
1709+ *
1710+ * This program is free software; you can redistribute it and/or modify
1711+ * it under the terms of the GNU Lesser General Public License as published by
1712+ * the Free Software Foundation; version 3.
1713+ *
1714+ * This program is distributed in the hope that it will be useful,
1715+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1716+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1717+ * GNU Lesser General Public License for more details.
1718+ *
1719+ * You should have received a copy of the GNU Lesser General Public License
1720+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1721+ */
1722+
1723+import QtQuick 2.4
1724+
1725+/*!
1726+ \qmltype PageColumnsLayout
1727+ \inqmlmodule Ubuntu.Components 1.3
1728+ \since Ubuntu.Components 1.3
1729+ \ingroup ubuntu
1730+ \brief Component configuring a layout in an AdaptivePageLayout component.
1731+
1732+ The component specifies the column configuration of a specific layout. The layout
1733+ will have as many columns as many PageColumn elements will be declared. The layout
1734+ will be activated when the \l when property evaluates to \c true. There can be
1735+ many layouts evaluated to true, only the first one evaluated to true in the
1736+ \l AdaptivePageLayout::layouts list will be activated.
1737+
1738+ \qml
1739+ import QtQuick 2.4
1740+ import Ubuntu.Components 1.3
1741+
1742+ MainView {
1743+ width: units.gu(100)
1744+ height: units.gu(60)
1745+
1746+ AdaptivePageLayout {
1747+ anchors.fill: parent
1748+ primaryPage: page1
1749+ layouts: [
1750+ PageColumnsLayout {
1751+ when: width > units.gu(80)
1752+ // column #0
1753+ PageColumn {
1754+ minimumWidth: units.gu(30)
1755+ maximumWidth: units.gu(60)
1756+ preferredWidth: units.gu(40)
1757+ }
1758+ // column #1
1759+ PageColumn {
1760+ fillWidth: true
1761+ }
1762+ },
1763+ PageColumnsLayout {
1764+ when: true
1765+ PageColumn {
1766+ fillWidth: true
1767+ minimumWidth: units.gu(10)
1768+ }
1769+ }
1770+ ]
1771+
1772+ Page {
1773+ id: page1
1774+ title: "Main page"
1775+ Column {
1776+ Button {
1777+ text: "Add Page2 above " + page1.title
1778+ onClicked: page1.pageStack.addPageToCurrentColumn(page1, page2)
1779+ }
1780+ Button {
1781+ text: "Add Page3 next to " + page1.title
1782+ onClicked: page1.pageStack.addPageToNextColumn(page1, page3)
1783+ }
1784+ }
1785+ }
1786+ Page {
1787+ id: page2
1788+ title: "Page #2"
1789+ }
1790+ Page {
1791+ id: page3
1792+ title: "Page #3"
1793+ }
1794+ }
1795+ }
1796+ \endqml
1797+ In the example above the second PageColumnLayout's condition is always set to
1798+ true, which means that that the layout will be always active unless the first
1799+ layout's condition evaluates to true. The layout overrides the single column
1800+ minimumWidth default value. Note that \l PageColumn::fillWidth must be also set.
1801+
1802+ \note When none of the conditions is met, a single column layout will be used.
1803+
1804+ \sa PageColumn
1805+ */
1806+QtObject {
1807+ id: layout
1808+
1809+ /*!
1810+ Condition activating the layout. Defaults to false.
1811+ */
1812+ property bool when: false
1813+
1814+ /*!
1815+ \qmlproperty list<PageColumn> data
1816+ \default
1817+ Default property holding the PageColumn elements configuring each column.
1818+ */
1819+ default property alias data: layout.__data
1820+ property list<PageColumn> __data
1821+}
1822
1823=== modified file 'src/Ubuntu/Components/1.3/PageWrapper.qml'
1824--- src/Ubuntu/Components/1.3/PageWrapper.qml 2015-06-15 07:45:34 +0000
1825+++ src/Ubuntu/Components/1.3/PageWrapper.qml 2015-09-08 04:09:38 +0000
1826@@ -15,7 +15,7 @@
1827 */
1828
1829 import QtQuick 2.4
1830-import "../1.2/PageWrapperUtils.js" as Utils
1831+import "PageWrapperUtils.js" as Utils
1832
1833 /*!
1834 \internal
1835@@ -66,6 +66,22 @@
1836 property Item pageHolder
1837
1838 /*!
1839+ Instructs to load the page synchronously or not. Used by AdaptivePageLayout.
1840+ True by default to keep PageStack integrity.
1841+ */
1842+ property bool synchronous: true
1843+
1844+ /*!
1845+ Incubator for the asynchronous page creation
1846+ */
1847+ property var incubator: null
1848+
1849+ /*!
1850+ Signal emitted when incubator completes page loading.
1851+ */
1852+ signal pageLoaded()
1853+
1854+ /*!
1855 Returns true if the current PageWrapper is a child of the given page
1856 */
1857 function childOf(page) {
1858@@ -114,7 +130,14 @@
1859 if (pageWrapper.object) pageWrapper.object = null;
1860 Utils.initPage(pageWrapper);
1861 if (pageWrapper.active && reference) {
1862- Utils.activate(pageWrapper);
1863+ if ((pageWrapper.incubator && pageWrapper.incubator.status == Component.Ready) || pageWrapper.object) {
1864+ Utils.activate(pageWrapper);
1865+ } else {
1866+ // asynchronous, connect page activation
1867+ pageLoaded.connect(function () {
1868+ Utils.activate(pageWrapper);
1869+ });
1870+ }
1871 }
1872 }
1873
1874
1875=== added file 'src/Ubuntu/Components/1.3/PageWrapperUtils.js'
1876--- src/Ubuntu/Components/1.3/PageWrapperUtils.js 1970-01-01 00:00:00 +0000
1877+++ src/Ubuntu/Components/1.3/PageWrapperUtils.js 2015-09-08 04:09:38 +0000
1878@@ -0,0 +1,167 @@
1879+/*
1880+ * Copyright 2015 Canonical Ltd.
1881+ *
1882+ * This program is free software; you can redistribute it and/or modify
1883+ * it under the terms of the GNU Lesser General Public License as published by
1884+ * the Free Software Foundation; version 3.
1885+ *
1886+ * This program is distributed in the hope that it will be useful,
1887+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1888+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1889+ * GNU Lesser General Public License for more details.
1890+ *
1891+ * You should have received a copy of the GNU Lesser General Public License
1892+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1893+ */
1894+
1895+//.pragma library // FIXME: cannot refer to Component.Error if I use this.
1896+// FIXME: ideally we would make this a stateless library, but that breaks applications
1897+// that rely on accessing context variables in pages that were pushed on a PageStack
1898+// by url (PageStack.push("FileName.qml")) because of a Qt bug:
1899+// https://bugreports.qt-project.org/browse/QTBUG-31347
1900+
1901+/*!
1902+ \internal
1903+ Incubator wrapper object. Used when page is loaded asynchronously.
1904+ */
1905+
1906+function Incubator(pageWrapper, pageComponent) {
1907+ // private variable for QmlIncubatorObject
1908+ var incubator = null;
1909+
1910+ // public API
1911+ this.status = Component.Ready;
1912+ this.object = null;
1913+ this.onStatusChanged = null;
1914+ this.forceCompletion = function () {
1915+ if (incubator) {
1916+ incubator.forceCompletion();
1917+ }
1918+ }
1919+
1920+ // internal function to catch status changes
1921+ function incubatorStatusChanged(status) {
1922+ // update wrapper incubator fields
1923+ pageWrapper.incubator.status = status;
1924+ pageWrapper.incubator.object = pageWrapper.object = incubator.object;
1925+
1926+ // emit pageWrapper's pageLoaded signal to complete page activation and loading
1927+ if (status === Component.Ready) {
1928+ pageWrapper.pageLoaded();
1929+ }
1930+
1931+ // forward state change to the user
1932+ if (pageWrapper.incubator.onStatusChanged) {
1933+ // call onStatusChanged
1934+ pageWrapper.incubator.onStatusChanged(status);
1935+ }
1936+
1937+ // cleanup of ready or error
1938+ if (status !== Component.Loading) {
1939+ pageWrapper.incubator = null;
1940+ incubator = null;
1941+ }
1942+ }
1943+
1944+ if (pageWrapper.properties) {
1945+ incubator = pageComponent.incubateObject(pageWrapper, pageWrapper.properties);
1946+ } else {
1947+ incubator = pageComponent.incubateObject(pageWrapper);
1948+ }
1949+
1950+ this.status = incubator.status;
1951+ if (incubator.status != Component.Ready) {
1952+ incubator.onStatusChanged = incubatorStatusChanged;
1953+ } else {
1954+ incubatorStatusChanged(incubator.status);
1955+ }
1956+}
1957+
1958+/*******************************************************
1959+ *
1960+ */
1961+/*!
1962+ \internal
1963+ Initialize pageWrapper.object.
1964+ */
1965+function initPage(pageWrapper) {
1966+ var pageComponent;
1967+
1968+ if (pageWrapper.reference.createObject) {
1969+ // page reference is a component
1970+ pageComponent = pageWrapper.reference;
1971+ } else if (typeof pageWrapper.reference == "string") {
1972+ // page reference is a string (url)
1973+ pageComponent = Qt.createComponent(pageWrapper.reference);
1974+ }
1975+
1976+ // PageWrapper can override the synchronous loading
1977+ var synchronous = pageWrapper.hasOwnProperty("synchronous") ? pageWrapper.synchronous : true;
1978+
1979+ if (pageComponent) {
1980+ if (pageComponent.status === Component.Error) {
1981+ throw new Error("Error while loading page: " + pageComponent.errorString());
1982+ } else {
1983+ // create the object
1984+ pageWrapper.incubator = new Incubator(pageWrapper, pageComponent);
1985+ if (synchronous) {
1986+ pageWrapper.incubator.forceCompletion();
1987+ }
1988+ pageWrapper.canDestroy = true;
1989+ }
1990+ } else {
1991+ // page reference is an object
1992+ pageWrapper.object = pageWrapper.reference;
1993+ pageWrapper.object.parent = pageWrapper;
1994+ pageWrapper.canDestroy = false;
1995+
1996+ // copy the properties to the page object
1997+ for (var prop in pageWrapper.properties) {
1998+ if (pageWrapper.properties.hasOwnProperty(prop)) {
1999+ pageWrapper.object[prop] = pageWrapper.properties[prop];
2000+ }
2001+ }
2002+ }
2003+
2004+ return pageWrapper.object;
2005+}
2006+
2007+/*!
2008+ \internal
2009+ Create the page object if needed, and make the page object visible.
2010+ */
2011+function activate(pageWrapper) {
2012+ if (!pageWrapper.object) {
2013+ initPage(pageWrapper);
2014+ }
2015+
2016+ // Having the same page pushed multiple times on a stack changes
2017+ // the parent of the page object. Change it back here.
2018+ pageWrapper.object.parent = pageWrapper;
2019+
2020+ // Some page objects are invisible initially. Make visible.
2021+
2022+ pageWrapper.object.visible = true;
2023+ pageWrapper.active = true;
2024+}
2025+
2026+/*!
2027+ \internal
2028+ Hide page object.
2029+ */
2030+function deactivate(pageWrapper) {
2031+ pageWrapper.active = false;
2032+}
2033+
2034+/*!
2035+ \internal
2036+ Destroy the page object if pageWrapper.canDestroy is true.
2037+ Do nothing if pageWrapper.canDestroy is false.
2038+ */
2039+function destroyObject(pageWrapper) {
2040+ if (pageWrapper.canDestroy) {
2041+ pageWrapper.object.destroy();
2042+ pageWrapper.object = null;
2043+ pageWrapper.canDestroy = false;
2044+ }
2045+}
2046
2047=== modified file 'src/Ubuntu/Components/1.3/TextField.qml'
2048--- src/Ubuntu/Components/1.3/TextField.qml 2015-08-11 17:15:59 +0000
2049+++ src/Ubuntu/Components/1.3/TextField.qml 2015-09-08 04:09:38 +0000
2050@@ -99,7 +99,7 @@
2051 \note During text selection all interactive parent Flickables are turned off.
2052 */
2053
2054-ActionItem {
2055+Ubuntu.ActionItem {
2056 id: control
2057
2058 implicitWidth: units.gu(25)
2059@@ -896,7 +896,7 @@
2060 }
2061 }
2062
2063- AbstractButton {
2064+ Ubuntu.AbstractButton {
2065 id: clearButton
2066 objectName: "clear_button"
2067 activeFocusOnPress: false
2068
2069=== modified file 'src/Ubuntu/Components/ComponentModule.pro'
2070--- src/Ubuntu/Components/ComponentModule.pro 2015-07-29 10:12:07 +0000
2071+++ src/Ubuntu/Components/ComponentModule.pro 2015-09-08 04:09:38 +0000
2072@@ -25,7 +25,6 @@
2073
2074 #1.2
2075 QML_FILES += 1.2/AbstractButton.qml \
2076- 1.2/ActionItem.qml \
2077 1.2/ActionList.qml \
2078 1.2/ActivityIndicator.qml \
2079 1.2/AnimatedItem.qml \
2080@@ -81,9 +80,7 @@
2081 1.2/UbuntuNumberAnimation.qml
2082
2083 #1.3
2084-QML_FILES += 1.3/AbstractButton.qml \
2085- 1.3/ActionBar.qml \
2086- 1.3/ActionItem.qml \
2087+QML_FILES += 1.3/ActionBar.qml \
2088 1.3/ActionList.qml \
2089 1.3/ActivityIndicator.qml \
2090 1.3/AdaptivePageLayout.qml \
2091@@ -92,12 +89,10 @@
2092 1.3/Button.qml \
2093 1.3/Captions.qml \
2094 1.3/CheckBox.qml \
2095- 1.3/ColumnMetrics.qml \
2096 1.3/ComboButton.qml \
2097 1.3/CrossFadeImage.qml \
2098 1.3/dateUtils.js \
2099 1.3/DraggingArea.qml \
2100- 1.3/Header.qml \
2101 1.3/InputHandler.qml \
2102 1.3/Label.qml \
2103 1.3/MainViewBase.qml \
2104@@ -114,6 +109,7 @@
2105 1.3/PageTreeNode.qml \
2106 1.3/pageUtils.js \
2107 1.3/PageWrapper.qml \
2108+ 1.3/PageWrapperUtils.js \
2109 1.3/Panel.qml \
2110 1.3/ProgressBar.qml \
2111 1.3/PullToRefresh.qml \
2112@@ -137,9 +133,12 @@
2113 1.3/UbuntuListView.qml \
2114 1.3/UbuntuNumberAnimation.qml \
2115 1.3/ListItemPopover.qml \
2116- 1.3/BottomEdgeHint.qml
2117+ 1.3/BottomEdgeHint.qml \
2118+ 1.3/PageColumn.qml \
2119+ 1.3/PageColumnsLayout.qml
2120
2121-OTHER_FILES+= 1.3/CrossFadeImage.qdoc \
2122+OTHER_FILES+= qmldir \
2123+ 1.3/CrossFadeImage.qdoc \
2124 1.3/UbuntuListView11.qdoc \
2125 1.3/Page.qdoc \
2126 1.3/PageHeadConfiguration.qdoc \
2127
2128=== modified file 'src/Ubuntu/Components/ListItems/1.3/SingleControl.qml'
2129--- src/Ubuntu/Components/ListItems/1.3/SingleControl.qml 2015-04-29 07:21:29 +0000
2130+++ src/Ubuntu/Components/ListItems/1.3/SingleControl.qml 2015-09-08 04:09:38 +0000
2131@@ -54,7 +54,8 @@
2132
2133 /*! \internal */
2134 onClicked: if (control && control.enabled && control.hasOwnProperty("clicked")) control.clicked()
2135- pressed: __mouseArea.pressed || (control && control.hasOwnProperty("pressed") && control.pressed)
2136+ /*! \internal */
2137+ property bool pressed: __mouseArea.pressed || (control && control.hasOwnProperty("pressed") && control.pressed)
2138 /*! \internal */
2139 onPressedChanged: if (control && control.enabled && control.hasOwnProperty("pressed")) control.pressed = singleControlListItem.pressed
2140
2141
2142=== modified file 'src/Ubuntu/Components/Popups/1.3/Popover.qml'
2143--- src/Ubuntu/Components/Popups/1.3/Popover.qml 2015-07-19 17:54:49 +0000
2144+++ src/Ubuntu/Components/Popups/1.3/Popover.qml 2015-09-08 04:09:38 +0000
2145@@ -210,7 +210,7 @@
2146 objectName: "popover_foreground"
2147
2148 //styling properties
2149- property real minimumWidth: units.gu(25)
2150+ property real minimumWidth: units.gu(40)
2151
2152 property real maxWidth: dismissArea ? (internal.portrait ? dismissArea.width : dismissArea.width * 3/4) : 0.0
2153 property real maxHeight: dismissArea ? (internal.portrait ? dismissArea.height * 3/4 : dismissArea.height) : 0.0
2154
2155=== modified file 'src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml'
2156--- src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml 2015-07-22 18:57:58 +0000
2157+++ src/Ubuntu/Components/Themes/Ambiance/1.2/ListItemStyle.qml 2015-09-08 04:09:38 +0000
2158@@ -25,7 +25,7 @@
2159 * Take over the ListItem's index context property as repeater used in panel
2160 * overrides the property.
2161 */
2162- readonly property int listItemIndex: index
2163+ readonly property int listItemIndex: (typeof index !== "undefined") ? index : internals.childIndex()
2164
2165 /*
2166 * Coloring properties
2167@@ -343,6 +343,19 @@
2168 readonly property real threshold: units.gu(1.5)
2169 property bool snapIn: false
2170
2171+ // returns the child index of the ListItem when not used in model driven view
2172+ function childIndex() {
2173+ if (styledItem.parent) {
2174+ for (var i = 0; i < styledItem.parent.children.length; i++) {
2175+ if (styledItem.parent.children[i] == styledItem) {
2176+ return i;
2177+ }
2178+ }
2179+ } else {
2180+ return -1;
2181+ }
2182+ }
2183+
2184 // update snap direction
2185 function updateSnapDirection() {
2186 if (prevX < listItemStyle.x && (snapChangerLimit <= listItemStyle.x)) {
2187
2188=== modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml'
2189--- src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml 2015-05-22 10:48:49 +0000
2190+++ src/Ubuntu/Components/Themes/Ambiance/1.3/ActionBarStyle.qml 2015-09-08 04:09:38 +0000
2191@@ -87,8 +87,6 @@
2192 id: actionsOverflowPopover
2193 objectName: "actions_overflow_panel"
2194
2195- backgroundColor: "white"
2196-
2197 // Ensure the popover closes when actions change and
2198 // the list item below may be destroyed before its
2199 // onClicked is executed. See bug
2200
2201=== removed file 'src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml'
2202--- src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml 2015-04-24 14:07:02 +0000
2203+++ src/Ubuntu/Components/Themes/Ambiance/1.3/HeadDividerStyle.qml 1970-01-01 00:00:00 +0000
2204@@ -1,56 +0,0 @@
2205-/*
2206- * Copyright 2014 Canonical Ltd.
2207- *
2208- * This program is free software; you can redistribute it and/or modify
2209- * it under the terms of the GNU Lesser General Public License as published by
2210- * the Free Software Foundation; version 3.
2211- *
2212- * This program is distributed in the hope that it will be useful,
2213- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2214- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2215- * GNU Lesser General Public License for more details.
2216- *
2217- * You should have received a copy of the GNU Lesser General Public License
2218- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2219- */
2220-import QtQuick 2.4
2221-
2222-/*!
2223- This component is DEPRECATED and no longer used. The divider is now a simple line.
2224- */
2225-Item {
2226- id: dividerStyle
2227-
2228- property color color: styledItem.backgroundColor
2229-
2230- // Do not make the following two colors part of the style API as they may be deprecated soon.
2231- property color topColor: Qt.darker(color, 1.1)
2232- property color bottomColor: Qt.lighter(color, 1.2)
2233-
2234- Rectangle {
2235- anchors.fill: parent
2236- color: dividerStyle.color
2237-
2238- gradient: Gradient {
2239- // top shadow
2240- GradientStop {
2241- position: 0.02
2242- color: dividerStyle.topColor
2243- }
2244- // middle (background)
2245- GradientStop {
2246- position: 0.05
2247- color: dividerStyle.color
2248- }
2249- GradientStop {
2250- position: 0.95
2251- color: dividerStyle.color
2252- }
2253- // bottom highlight
2254- GradientStop {
2255- position: 0.98
2256- color: dividerStyle.bottomColor
2257- }
2258- }
2259- }
2260-}
2261
2262=== removed file 'src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml'
2263--- src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml 2015-04-24 14:07:02 +0000
2264+++ src/Ubuntu/Components/Themes/Ambiance/1.3/HeaderStyle.qml 1970-01-01 00:00:00 +0000
2265@@ -1,124 +0,0 @@
2266-/*
2267- * Copyright 2015 Canonical Ltd.
2268- *
2269- * This program is free software; you can redistribute it and/or modify
2270- * it under the terms of the GNU Lesser General Public License as published by
2271- * the Free Software Foundation; version 3.
2272- *
2273- * This program is distributed in the hope that it will be useful,
2274- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2275- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2276- * GNU Lesser General Public License for more details.
2277- *
2278- * You should have received a copy of the GNU Lesser General Public License
2279- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2280- */
2281-import QtQuick 2.4
2282-import Ubuntu.Components 1.3
2283-
2284-Item {
2285- id: headerStyle
2286- /*!
2287- The height of the headercontents, which is the full height of
2288- the header minus the separators shown at the bottom of it.
2289- */
2290- property real contentHeight: units.gu(7.5)
2291-
2292- /*!
2293- The source of the image that separates the header from the contents of a \l MainView.
2294- The separator will be drawn over the contents.
2295- */
2296- property url separatorSource: Qt.resolvedUrl("../artwork/PageHeaderBaseDividerLight.sci")
2297-
2298- /*!
2299- The source of an additional image attached to the bottom of the separator. The contents
2300- of the \l MainView will be drawn on top of the separator bottom image.
2301- */
2302- property url separatorBottomSource: Qt.resolvedUrl("../artwork/PageHeaderBaseDividerBottom.png")
2303-
2304- property int fontWeight: Font.Light
2305- property string fontSize: "x-large"
2306- property color textColor: theme.palette.selected.backgroundText
2307- property real textLeftMargin: units.gu(2)
2308-
2309- implicitHeight: headerStyle.contentHeight + separator.height + separatorBottom.height
2310-
2311- /*!
2312- \internal
2313- Tabs needs to call sync of the TabBar
2314- */
2315- property TabBar __tabBar: tabBarLoader.sourceComponent ? tabBarLoader.item : null
2316-
2317- BorderImage {
2318- id: separator
2319- anchors {
2320- bottom: parent.bottom
2321- left: parent.left
2322- right: parent.right
2323- }
2324- source: headerStyle.separatorSource
2325- }
2326- Image {
2327- id: separatorBottom
2328- anchors {
2329- top: separator.bottom
2330- left: parent.left
2331- right: parent.right
2332- }
2333- source: headerStyle.separatorBottomSource
2334- }
2335-
2336- Item {
2337- id: foreground
2338- anchors {
2339- left: parent.left
2340- right: parent.right
2341- top: parent.top
2342- }
2343- height: headerStyle.contentHeight
2344-
2345- Label {
2346- LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft
2347-
2348- anchors {
2349- left: parent.left
2350- verticalCenter: parent.verticalCenter
2351- leftMargin: headerStyle.textLeftMargin
2352- }
2353- text: styledItem.title
2354- font.weight: headerStyle.fontWeight
2355- visible: !styledItem.tabsModel && !styledItem.contents
2356- fontSize: headerStyle.fontSize
2357- color: headerStyle.textColor
2358- }
2359-
2360- Binding {
2361- target: styledItem.contents
2362- property: "anchors.fill"
2363- value: foreground
2364- when: styledItem.contents
2365- }
2366- Binding {
2367- target: styledItem.contents
2368- property: "parent"
2369- value: foreground
2370- when: styledItem.contents
2371- }
2372-
2373- Loader {
2374- id: tabBarLoader
2375- sourceComponent: styledItem.tabsModel && !styledItem.contents ? tabBarComponent : null
2376- anchors.fill: parent
2377- }
2378-
2379- Component {
2380- id: tabBarComponent
2381- TabBar {
2382- id: tabBar
2383- anchors.fill: parent
2384- model: styledItem.tabsModel
2385- animate: styledItem.animate
2386- }
2387- }
2388- }
2389-}
2390
2391=== modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml'
2392--- src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-07-22 18:57:58 +0000
2393+++ src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-09-08 04:09:38 +0000
2394@@ -337,6 +337,7 @@
2395 property real snapChangerLimit: 0.0
2396 readonly property real threshold: units.gu(1.5)
2397 property bool snapIn: false
2398+ property bool completed: false
2399
2400 // update snap direction
2401 function updateSnapDirection() {
2402@@ -419,4 +420,68 @@
2403 function rebound() {
2404 snapAnimation.snapTo(0);
2405 }
2406+
2407+ // expansion
2408+ Component.onCompleted: internals.completed = true
2409+ state: (internals.completed && styledItem.expansion.expanded) ? (listItemStyle.flickable ? "expandedWithFlickable" : "expandedNoFlickable") : ""
2410+ states: [
2411+ State {
2412+ name: "expandedNoFlickable"
2413+ PropertyChanges {
2414+ target: styledItem
2415+ height: styledItem.expansion.height
2416+ }
2417+ },
2418+ State {
2419+ name: "expandedWithFlickable"
2420+ PropertyChanges {
2421+ target: styledItem
2422+ height: styledItem.expansion.height
2423+ }
2424+ PropertyChanges {
2425+ target: listItemStyle.flickable
2426+ // we do not need to restore the original values
2427+ restoreEntryValues: false
2428+ // and we should not get any binding updates even
2429+ explicit: true
2430+ contentY: {
2431+ var bottom = styledItem.y + styledItem.expansion.height - listItemStyle.flickable.contentY + listItemStyle.flickable.originY;
2432+ var dy = bottom - listItemStyle.flickable.height;
2433+ if (dy > 0) {
2434+ return listItemStyle.flickable.contentY + dy - listItemStyle.flickable.originY;
2435+ } else {
2436+ return listItemStyle.flickable.contentY;
2437+ }
2438+ }
2439+ }
2440+ }
2441+ ]
2442+ transitions: [
2443+ Transition {
2444+ from: ""
2445+ to: "expandedWithFlickable"
2446+ reversible: true
2447+ enabled: listItemStyle.animatePanels
2448+ ParallelAnimation {
2449+ UbuntuNumberAnimation {
2450+ target: listItemStyle.flickable
2451+ property: "contentY"
2452+ }
2453+ UbuntuNumberAnimation {
2454+ target: styledItem
2455+ property: "height"
2456+ }
2457+ }
2458+ },
2459+ Transition {
2460+ from: ""
2461+ to: "expandedNoFlickable"
2462+ reversible: true
2463+ enabled: listItemStyle.animatePanels
2464+ UbuntuNumberAnimation {
2465+ target: styledItem
2466+ property: "height"
2467+ }
2468+ }
2469+ ]
2470 }
2471
2472=== modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml'
2473--- src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml 2015-04-29 08:55:31 +0000
2474+++ src/Ubuntu/Components/Themes/Ambiance/1.3/OverflowPanel.qml 2015-09-08 04:09:38 +0000
2475@@ -32,7 +32,7 @@
2476 /*!
2477 The background color of the tabs panel and the actions overflow panel.
2478 */
2479- property color backgroundColor: styledItem.panelColor
2480+ property color backgroundColor: theme.palette.normal.background
2481
2482 /*!
2483 The background color of the tapped item in the panel.
2484
2485=== modified file 'src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro'
2486--- src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro 2015-06-18 08:03:55 +0000
2487+++ src/Ubuntu/Components/Themes/Ambiance/Ambiance.pro 2015-09-08 04:09:38 +0000
2488@@ -84,8 +84,6 @@
2489 1.3/DialerHandStyle.qml \
2490 1.3/DialerStyle.qml \
2491 1.3/DialogForegroundStyle.qml \
2492- 1.3/HeadDividerStyle.qml \
2493- 1.3/HeaderStyle.qml \
2494 1.3/HighlightMagnifier.qml \
2495 1.3/ListItemOptionSelectorStyle.qml \
2496 1.3/ListItemStyle.qml \
2497
2498=== modified file 'src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp'
2499--- src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp 2014-09-01 06:56:39 +0000
2500+++ src/Ubuntu/Components/plugin/adapters/actionsproxy_p.cpp 2015-09-08 04:09:38 +0000
2501@@ -90,18 +90,18 @@
2502 }
2503 if (watch) {
2504 // connect to action proxy
2505- QObject::connect(context, SIGNAL(activeChanged(bool)),
2506- this, SLOT(handleContextActivation(bool)),
2507+ QObject::connect(context, SIGNAL(activeChanged()),
2508+ this, SLOT(handleContextActivation()),
2509 Qt::DirectConnection);
2510 } else {
2511 // disconnect
2512- QObject::disconnect(context, SIGNAL(activeChanged(bool)),
2513- this, SLOT(handleContextActivation(bool)));
2514+ QObject::disconnect(context, SIGNAL(activeChanged()),
2515+ this, SLOT(handleContextActivation()));
2516 }
2517 }
2518
2519 // handles the local context activation
2520-void ActionProxy::handleContextActivation(bool active)
2521+void ActionProxy::handleContextActivation()
2522 {
2523 // sender is the context changing activation
2524 UCActionContext *context = qobject_cast<UCActionContext*>(sender());
2525@@ -110,7 +110,7 @@
2526 }
2527 // deactivate the previous context if any
2528 if (!m_activeContext.isNull()) {
2529- if (!active) {
2530+ if (!context->active()) {
2531 // the slot has been called due to the previous active deactivation,
2532 // so perform system cleanup
2533 clearContextActions(m_activeContext);
2534@@ -124,7 +124,7 @@
2535 m_activeContext->setActive(false);
2536 }
2537 }
2538- if (active) {
2539+ if (context->active()) {
2540 // publish the context's actions to the system
2541 publishContextActions(context);
2542 context->markActionsPublished(true);
2543
2544=== modified file 'src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h'
2545--- src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h 2014-09-01 06:56:39 +0000
2546+++ src/Ubuntu/Components/plugin/adapters/actionsproxy_p.h 2015-09-08 04:09:38 +0000
2547@@ -48,7 +48,7 @@
2548
2549 protected Q_SLOTS:
2550 void watchContextActivation(UCActionContext *context, bool watch);
2551- void handleContextActivation(bool active);
2552+ void handleContextActivation();
2553 virtual void clearContextActions(UCActionContext *context);
2554 virtual void publishContextActions(UCActionContext *context);
2555
2556
2557=== modified file 'src/Ubuntu/Components/plugin/i18n.cpp'
2558--- src/Ubuntu/Components/plugin/i18n.cpp 2015-03-03 13:47:48 +0000
2559+++ src/Ubuntu/Components/plugin/i18n.cpp 2015-09-08 04:09:38 +0000
2560@@ -17,6 +17,7 @@
2561 */
2562
2563 #include "i18n.h"
2564+#include "timeutils_p.h"
2565 #include <QtCore/QDir>
2566
2567 namespace C {
2568@@ -252,3 +253,76 @@
2569 Q_UNUSED(context);
2570 return text;
2571 }
2572+/*!
2573+ * \qmlmethod string i18n::relativeDateTime(datetime dateTime)
2574+ * Translate a datetime based on proximity to current time.
2575+ */
2576+QString UbuntuI18n::relativeDateTime(const QDateTime& datetime)
2577+{
2578+ QDateTime relativeTo(QDateTime::currentDateTime());
2579+ const date_proximity_t prox = getDateProximity(relativeTo, datetime);
2580+
2581+ switch (prox) {
2582+ case DATE_PROXIMITY_NOW:
2583+ /* TRANSLATORS: Time based "this is happening/happened now" */
2584+ return dtr("ubuntu-ui-toolkit", "Now");
2585+
2586+ case DATE_PROXIMITY_HOUR:
2587+ {
2588+ qint64 diff = datetime.toMSecsSinceEpoch() - relativeTo.toMSecsSinceEpoch();
2589+ qint64 minutes = qRound(float(diff) / 60000);
2590+ if (minutes < 0) {
2591+ return dtr("ubuntu-ui-toolkit", "%1 minute ago", "%1 minutes ago", qAbs(minutes)).arg(qAbs(minutes));
2592+ }
2593+ return dtr("ubuntu-ui-toolkit", "%1 minute", "%1 minutes", minutes).arg(minutes);
2594+ }
2595+
2596+ case DATE_PROXIMITY_TODAY:
2597+ /* en_US example: "1:00 PM" */
2598+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2599+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2600+ return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "h:mm ap"):
2601+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2602+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2603+ dtr("ubuntu-ui-toolkit", "HH:mm"));
2604+
2605+ case DATE_PROXIMITY_YESTERDAY:
2606+ /* en_US example: "Yesterday 13:00" */
2607+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2608+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2609+ return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "'Yesterday\u2003'h:mm ap") :
2610+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2611+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2612+ dtr("ubuntu-ui-toolkit", "'Yesterday\u2003'HH:mm"));
2613+
2614+ case DATE_PROXIMITY_TOMORROW:
2615+ /* en_US example: "Tomorrow 1:00 PM" */
2616+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2617+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2618+ return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "'Tomorrow\u2003'h:mm ap") :
2619+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2620+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2621+ dtr("ubuntu-ui-toolkit", "'Tomorrow\u2003'HH:mm"));
2622+
2623+ case DATE_PROXIMITY_LAST_WEEK:
2624+ case DATE_PROXIMITY_NEXT_WEEK:
2625+ /* en_US example: "Fri 1:00 PM" */
2626+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2627+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2628+ return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "ddd'\u2003'h:mm ap") :
2629+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2630+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2631+ dtr("ubuntu-ui-toolkit", "ddd'\u2003'HH:mm"));
2632+
2633+ case DATE_PROXIMITY_FAR_BACK:
2634+ case DATE_PROXIMITY_FAR_FORWARD:
2635+ default:
2636+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2637+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2638+ return datetime.toString(isLocale12h() ? dtr("ubuntu-ui-toolkit", "ddd d MMM'\u2003'h:mm ap") :
2639+ /* TRANSLATORS: Please translated these to your locale datetime format using the format specified by
2640+ https://qt-project.org/doc/qt-5-snapshot/qdatetime.html#fromString-2 */
2641+ dtr("ubuntu-ui-toolkit", "ddd d MMM'\u2003'HH:mm"));
2642+ }
2643+ return datetime.toString(Qt::DefaultLocaleShortDate);
2644+}
2645
2646=== modified file 'src/Ubuntu/Components/plugin/i18n.h'
2647--- src/Ubuntu/Components/plugin/i18n.h 2015-02-03 18:11:32 +0000
2648+++ src/Ubuntu/Components/plugin/i18n.h 2015-09-08 04:09:38 +0000
2649@@ -50,6 +50,7 @@
2650 Q_INVOKABLE QString dctr(const QString& domain, const QString& context, const QString& text);
2651 Q_INVOKABLE QString tag(const QString& text);
2652 Q_INVOKABLE QString tag(const QString& context, const QString& text);
2653+ Q_INVOKABLE QString relativeDateTime(const QDateTime& datetime);
2654
2655 // getter
2656 QString domain() const;
2657
2658=== modified file 'src/Ubuntu/Components/plugin/plugin.cpp'
2659--- src/Ubuntu/Components/plugin/plugin.cpp 2015-08-12 09:54:40 +0000
2660+++ src/Ubuntu/Components/plugin/plugin.cpp 2015-09-08 04:09:38 +0000
2661@@ -62,6 +62,9 @@
2662 #include "uclistitemstyle.h"
2663 #include "ucserviceproperties.h"
2664 #include "ucnamespace.h"
2665+#include "ucactionitem.h"
2666+#include "uchaptics.h"
2667+#include "ucabstractbutton.h"
2668
2669 #include <sys/types.h>
2670 #include <unistd.h>
2671@@ -116,6 +119,14 @@
2672 return new UCNamespaceV13();
2673 }
2674
2675+static QObject *registerHaptics(QQmlEngine *engine, QJSEngine *scriptEngine)
2676+{
2677+ Q_UNUSED(engine)
2678+ Q_UNUSED(scriptEngine)
2679+
2680+ return new UCHaptics();
2681+}
2682+
2683 void UbuntuComponentsPlugin::initializeBaseUrl()
2684 {
2685 if (!m_baseUrl.isValid()) {
2686@@ -174,6 +185,8 @@
2687 qmlRegisterSingletonType<UCUriHandler>(uri, major, minor, "UriHandler", registerUriHandler);
2688 qmlRegisterType<UCMouse>(uri, major, minor, "Mouse");
2689 qmlRegisterType<UCInverseMouse>(uri, major, minor, "InverseMouse");
2690+ qmlRegisterType<UCActionItem>(uri, major, minor, "ActionItem");
2691+ qmlRegisterSingletonType<UCHaptics>(uri, major, minor, "Haptics", registerHaptics);
2692 }
2693
2694 void UbuntuComponentsPlugin::registerTypes(const char *uri)
2695@@ -211,6 +224,8 @@
2696
2697 // register 1.3 API
2698 qmlRegisterType<UCListItem13>(uri, 1, 3, "ListItem");
2699+ qmlRegisterType<UCListItemExpansion>();
2700+ qmlRegisterUncreatableType<UCViewItemsAttached13>(uri, 1, 3, "ViewItems", "No create");
2701 qmlRegisterType<UCTheme>(uri, 1, 3, "ThemeSettings");
2702 qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem");
2703 qmlRegisterSingletonType<UCNamespaceV13>(uri, 1, 3, "Ubuntu", registerUbuntuNamespace13);
2704@@ -220,6 +235,7 @@
2705 qmlRegisterType<UCUbuntuShape, 2>(uri, 1, 3, "UbuntuShape");
2706 qmlRegisterType<UCProportionalShape>(uri, 1, 3, "ProportionalShape");
2707 qmlRegisterType<LiveTimer>(uri, 1, 3, "LiveTimer");
2708+ qmlRegisterType<UCAbstractButton>(uri, 1, 3, "AbstractButton");
2709 }
2710
2711 void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
2712@@ -244,6 +260,8 @@
2713
2714 UCDeprecatedTheme::instance().registerToContext(context);
2715
2716+ HapticsProxy::instance().setEngine(context->engine());
2717+
2718 context->setContextProperty("i18n", &UbuntuI18n::instance());
2719 ContextPropertyChangeListener *i18nChangeListener =
2720 new ContextPropertyChangeListener(context, "i18n");
2721
2722=== modified file 'src/Ubuntu/Components/plugin/plugin.pri'
2723--- src/Ubuntu/Components/plugin/plugin.pri 2015-08-18 22:14:51 +0000
2724+++ src/Ubuntu/Components/plugin/plugin.pri 2015-09-08 04:09:38 +0000
2725@@ -80,7 +80,10 @@
2726 $$PWD/ucstylehints.h \
2727 $$PWD/livetimer.h \
2728 $$PWD/livetimer_p.h \
2729- $$PWD/timeutils_p.h
2730+ $$PWD/timeutils_p.h \
2731+ $$PWD/ucactionitem.h \
2732+ $$PWD/uchaptics.h \
2733+ $$PWD/ucabstractbutton.h
2734
2735 SOURCES += $$PWD/plugin.cpp \
2736 $$PWD/uctheme.cpp \
2737@@ -127,12 +130,16 @@
2738 $$PWD/ucserviceproperties.cpp \
2739 $$PWD/privates/listitemdragarea.cpp \
2740 $$PWD/privates/listitemdraghandler.cpp \
2741+ $$PWD/privates/listitemexpansion.cpp \
2742 $$PWD/ucnamespace.cpp \
2743 $$PWD/ucdeprecatedtheme.cpp \
2744 $$PWD/ucdefaulttheme.cpp \
2745 $$PWD/ucstylehints.cpp \
2746 $$PWD/livetimer.cpp \
2747- $$PWD/livetimer_p.cpp
2748+ $$PWD/livetimer_p.cpp \
2749+ $$PWD/ucactionitem.cpp \
2750+ $$PWD/uchaptics.cpp \
2751+ $$PWD/ucabstractbutton.cpp
2752
2753 # adapters
2754 SOURCES += $$PWD/adapters/alarmsadapter_organizer.cpp
2755
2756=== modified file 'src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp'
2757--- src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp 2015-04-13 11:11:59 +0000
2758+++ src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp 2015-09-08 04:09:38 +0000
2759@@ -47,13 +47,12 @@
2760 setObjectName("drag_area");
2761 }
2762
2763-void ListItemDragArea::init()
2764+void ListItemDragArea::init(UCViewItemsAttached *viewItems)
2765 {
2766 setParentItem(static_cast<QQuickItem*>(parent()));
2767 QQuickAnchors *anchors = QQuickItemPrivate::get(this)->anchors();
2768 anchors->setFill(parentItem());
2769- viewAttached = static_cast<UCViewItemsAttached*>(
2770- qmlAttachedPropertiesObject<UCViewItemsAttached>(listView));
2771+ viewAttached = viewItems;
2772 reset();
2773 }
2774
2775
2776=== modified file 'src/Ubuntu/Components/plugin/privates/listitemdragarea.h'
2777--- src/Ubuntu/Components/plugin/privates/listitemdragarea.h 2015-02-24 15:57:53 +0000
2778+++ src/Ubuntu/Components/plugin/privates/listitemdragarea.h 2015-09-08 04:09:38 +0000
2779@@ -27,7 +27,7 @@
2780 Q_OBJECT
2781 public:
2782 explicit ListItemDragArea(QQuickItem *parent = 0);
2783- void init();
2784+ void init(UCViewItemsAttached *viewItems);
2785 void reset();
2786
2787 protected:
2788
2789=== added file 'src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp'
2790--- src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp 1970-01-01 00:00:00 +0000
2791+++ src/Ubuntu/Components/plugin/privates/listitemexpansion.cpp 2015-09-08 04:09:38 +0000
2792@@ -0,0 +1,106 @@
2793+/*
2794+ * Copyright 2015 Canonical Ltd.
2795+ *
2796+ * This program is free software; you can redistribute it and/or modify
2797+ * it under the terms of the GNU Lesser General Public License as published by
2798+ * the Free Software Foundation; version 3.
2799+ *
2800+ * This program is distributed in the hope that it will be useful,
2801+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2802+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2803+ * GNU Lesser General Public License for more details.
2804+ *
2805+ * You should have received a copy of the GNU Lesser General Public License
2806+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2807+ */
2808+
2809+#include "uclistitem.h"
2810+#include "uclistitem_p.h"
2811+
2812+UCListItemExpansion::UCListItemExpansion(QObject *parent)
2813+ : QObject(parent)
2814+ , m_listItem(static_cast<UCListItem13*>(parent))
2815+ , m_height(0.0)
2816+ , m_filtering(false)
2817+{
2818+}
2819+
2820+bool UCListItemExpansion::expandedLocked()
2821+{
2822+ UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem);
2823+ UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached);
2824+ return expanded() && !((viewItems->expansionFlags & UCViewItemsAttached::UnlockExpanded) == UCViewItemsAttached::UnlockExpanded);
2825+}
2826+
2827+void UCListItemExpansion::enableClickFiltering(bool enable)
2828+{
2829+ if (m_filtering == enable) {
2830+ return;
2831+ }
2832+ m_filtering = enable;
2833+ if (m_filtering) {
2834+ m_listItem->window()->installEventFilter(this);
2835+ } else {
2836+ m_listItem->window()->removeEventFilter(this);
2837+ }
2838+}
2839+
2840+// event filter for external mouse presses to collapse when pressed outside
2841+bool UCListItemExpansion::eventFilter(QObject *target, QEvent *event)
2842+{
2843+ if (event->type() == QEvent::MouseButtonPress) {
2844+ QMouseEvent *mouse = static_cast<QMouseEvent*>(event);
2845+ QQuickWindow *window = qobject_cast<QQuickWindow*>(target);
2846+ if (window) {
2847+ QPointF myPos(window->contentItem()->mapToItem(m_listItem, mouse->localPos()));
2848+ if (!m_listItem->contains(myPos)) {
2849+ UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem);
2850+ UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached);
2851+ if (viewItems) {
2852+ // collapse all as there can be only one expanded when the flag is set
2853+ viewItems->collapseAll();
2854+ }
2855+ }
2856+ }
2857+ }
2858+ return false;
2859+}
2860+
2861+
2862+bool UCListItemExpansion::expanded()
2863+{
2864+ UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem);
2865+ UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached);
2866+ return (viewItems && viewItems->expansionList.contains(listItem->index()));
2867+}
2868+
2869+void UCListItemExpansion::setExpanded(bool expanded)
2870+{
2871+ if (this->expanded() == expanded) {
2872+ return;
2873+ }
2874+ UCListItemPrivate *listItem = UCListItemPrivate::get(m_listItem);
2875+ UCViewItemsAttachedPrivate *viewItems = UCViewItemsAttachedPrivate::get(listItem->parentAttached);
2876+ if (viewItems) {
2877+ if (viewItems->expansionFlags & UCViewItemsAttached::Exclusive) {
2878+ // collapse all the expanded ones
2879+ viewItems->collapseAll();
2880+ }
2881+ if (expanded) {
2882+ viewItems->expand(listItem->index(), m_listItem);
2883+ } else {
2884+ viewItems->collapse(listItem->index());
2885+ }
2886+ }
2887+ UCListItemPrivate::get(m_listItem)->loadStyleItem();
2888+ // no need to emit changed signal, as ViewItems.expandedIndicesChanged is connected to the change signal
2889+}
2890+
2891+void UCListItemExpansion::setHeight(qreal height)
2892+{
2893+ if (m_height == height) {
2894+ return;
2895+ }
2896+ m_height = height;
2897+ Q_EMIT heightChanged();
2898+}
2899
2900=== modified file 'src/Ubuntu/Components/plugin/sortfiltermodel.cpp'
2901--- src/Ubuntu/Components/plugin/sortfiltermodel.cpp 2015-03-03 13:47:48 +0000
2902+++ src/Ubuntu/Components/plugin/sortfiltermodel.cpp 2015-09-08 04:09:38 +0000
2903@@ -113,9 +113,12 @@
2904 QSortFilterProxyModelQML::roleByName(const QString& roleName) const
2905 {
2906 const QHash<int, QByteArray> roles = roleNames();
2907- for(int role = 0; role < roles.count(); role++)
2908- if (roles[role] == roleName)
2909- return role;
2910+ QHashIterator<int, QByteArray> i(roles);
2911+ while (i.hasNext()) {
2912+ i.next();
2913+ if (i.value() == roleName)
2914+ return i.key();
2915+ }
2916 return 0;
2917 }
2918
2919
2920=== modified file 'src/Ubuntu/Components/plugin/timeutils_p.h'
2921--- src/Ubuntu/Components/plugin/timeutils_p.h 2015-07-20 15:34:32 +0000
2922+++ src/Ubuntu/Components/plugin/timeutils_p.h 2015-09-08 04:09:38 +0000
2923@@ -20,9 +20,33 @@
2924 #include "livetimer.h"
2925
2926 #include <QDateTime>
2927+#include <QLocale>
2928 #include <QObject>
2929 #include <QTimer>
2930
2931+/* Check the system locale setting to see if the format is 24-hour
2932+ time or 12-hour time */
2933+inline bool isLocale12h(void)
2934+{
2935+ QString strTimeFormat = QLocale::system().timeFormat();
2936+ QStringList includes; includes << "AP"; includes << "ap";
2937+ QStringList excludes; excludes << "H"; excludes << "HH";
2938+
2939+ Q_FOREACH(const QString& exclude, excludes) {
2940+ if (strTimeFormat.contains(exclude)) {
2941+ return false;
2942+ }
2943+ }
2944+
2945+ Q_FOREACH(const QString& include, includes) {
2946+ if (strTimeFormat.contains(include)) {
2947+ return true;
2948+ }
2949+ }
2950+
2951+ return false;
2952+}
2953+
2954 typedef enum
2955 {
2956 DATE_PROXIMITY_NOW,
2957
2958=== added file 'src/Ubuntu/Components/plugin/ucabstractbutton.cpp'
2959--- src/Ubuntu/Components/plugin/ucabstractbutton.cpp 1970-01-01 00:00:00 +0000
2960+++ src/Ubuntu/Components/plugin/ucabstractbutton.cpp 2015-09-08 04:09:38 +0000
2961@@ -0,0 +1,156 @@
2962+/*
2963+ * Copyright 2015 Canonical Ltd.
2964+ *
2965+ * This program is free software; you can redistribute it and/or modify
2966+ * it under the terms of the GNU Lesser General Public License as published by
2967+ * the Free Software Foundation; version 3.
2968+ *
2969+ * This program is distributed in the hope that it will be useful,
2970+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2971+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2972+ * GNU Lesser General Public License for more details.
2973+ *
2974+ * You should have received a copy of the GNU Lesser General Public License
2975+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2976+ */
2977+
2978+#include "ucabstractbutton.h"
2979+#include "uchaptics.h"
2980+#include <QtQuick/private/qquickitem_p.h>
2981+#include <QtQuick/private/qquickmousearea_p.h>
2982+#include <QtQml/private/qqmlglobal_p.h>
2983+
2984+/*!
2985+ \qmltype AbstractButton
2986+ \instantiates UCAbstractButton
2987+ \inqmlmodule Ubuntu.Components 1.1
2988+ \ingroup ubuntu
2989+ \brief The AbstractButton class defines the behavior of the button.
2990+
2991+ This class defines the behavior of the button. All components deriving from
2992+ this class support haptic feedback out of the box.
2993+
2994+ If an action is specified, the button's clicked signal will trigger the action.
2995+ Subclasses of AbstractButton can use other properties of action (for example
2996+ the text and iconName).
2997+*/
2998+
2999+/*!
3000+ *
3001+ * \qmlsignal AbstractButton::clicked()
3002+ * This handler is called when there is a mouse click on the button and the button
3003+ * is not disabled. If \l {ActionItem::action}{action} is defined, the action will be triggered.
3004+ */
3005+
3006+/*!
3007+ *
3008+ * \qmlsignal AbstractButton::pressAndHold()
3009+ * This handler is called when there is a long press.
3010+ */
3011+
3012+UCAbstractButton::UCAbstractButton(QQuickItem *parent)
3013+ : UCActionItem(parent)
3014+ , m_mouseArea(new QQuickMouseArea)
3015+ , m_acceptEvents(true)
3016+{
3017+ setActiveFocusOnPress(true);
3018+}
3019+
3020+bool UCAbstractButton::isPressAndHoldConnected()
3021+{
3022+ static QMetaMethod method = QMetaMethod::fromSignal(&UCAbstractButton::pressAndHold);
3023+ static int signalIdx = QMetaObjectPrivate::signalIndex(method);
3024+ return QObjectPrivate::get(this)->isSignalConnected(signalIdx);
3025+}
3026+
3027+void UCAbstractButton::classBegin()
3028+{
3029+ UCActionItem::classBegin();
3030+
3031+ // make sure we have the haptics set up!
3032+ HapticsProxy::instance().initialize();
3033+
3034+ // set up mouse area
3035+ QQml_setParent_noEvent(m_mouseArea, this);
3036+ m_mouseArea->setParentItem(this);
3037+ QQuickAnchors *anchors = QQuickItemPrivate::get(m_mouseArea)->anchors();
3038+ anchors->setFill(this);
3039+ m_mouseArea->setHoverEnabled(true);
3040+}
3041+
3042+void UCAbstractButton::componentComplete()
3043+{
3044+ UCActionItem::componentComplete();
3045+ // connect to the right slot, using macros so we get the proper slot
3046+ connect(this, SIGNAL(clicked()), this, SLOT(trigger()));
3047+
3048+ // bind mouse area
3049+ connect(m_mouseArea, &QQuickMouseArea::pressedChanged, this, &UCAbstractButton::pressedChanged);
3050+ connect(m_mouseArea, &QQuickMouseArea::hoveredChanged, this, &UCAbstractButton::hoveredChanged);
3051+ connect(m_mouseArea, SIGNAL(clicked(QQuickMouseEvent*)), this, SLOT(_q_mouseAreaClicked()));
3052+ if (isPressAndHoldConnected()) {
3053+ connect(m_mouseArea, SIGNAL(pressAndHold(QQuickMouseEvent*)), this, SLOT(_q_mouseAreaPressAndHold()));
3054+ }
3055+}
3056+
3057+// handle mouseClicked with Haptics
3058+void UCAbstractButton::_q_mouseAreaClicked()
3059+{
3060+ // required by the deprecated ListItem module
3061+ if (!m_acceptEvents) {
3062+ return;
3063+ }
3064+ // play haptics
3065+ HapticsProxy::instance().play(QVariant());
3066+ Q_EMIT clicked();
3067+}
3068+
3069+// handle pressAndHold
3070+void UCAbstractButton::_q_mouseAreaPressAndHold()
3071+{
3072+ // required by the deprecated ListItem module
3073+ if (!m_acceptEvents) {
3074+ return;
3075+ }
3076+ Q_EMIT pressAndHold();
3077+}
3078+
3079+// emit clicked when Enter/Return is pressed
3080+void UCAbstractButton::keyPressEvent(QKeyEvent *event)
3081+{
3082+ UCActionItem::keyPressEvent(event);
3083+
3084+ switch (event->key()) {
3085+ case Qt::Key_Enter:
3086+ case Qt::Key_Return:
3087+ // FIXME: space may also come here, however that depends on the button type
3088+ // (i.e default Dialog btn) so we may need to add that to Button
3089+ {
3090+ Q_EMIT clicked();
3091+ break;
3092+ }
3093+ }
3094+}
3095+
3096+/*!
3097+ * \qmlproperty bool AbstractButton::pressed
3098+ * True if the user presses a mouse button in the button's mouse area.
3099+ */
3100+bool UCAbstractButton::pressed() const
3101+{
3102+ return m_mouseArea ? m_mouseArea->pressed() : false;
3103+}
3104+
3105+/*!
3106+ * \qmlproperty bool AbstractButton::hovered
3107+ * True if the mouse cursor hovers over the button's mouse area.
3108+ */
3109+bool UCAbstractButton::hovered() const
3110+{
3111+ return m_mouseArea ? m_mouseArea->hovered() : false;
3112+}
3113+
3114+QQuickMouseArea *UCAbstractButton::privateMouseArea() const
3115+{
3116+ return m_mouseArea;
3117+}
3118
3119=== added file 'src/Ubuntu/Components/plugin/ucabstractbutton.h'
3120--- src/Ubuntu/Components/plugin/ucabstractbutton.h 1970-01-01 00:00:00 +0000
3121+++ src/Ubuntu/Components/plugin/ucabstractbutton.h 2015-09-08 04:09:38 +0000
3122@@ -0,0 +1,64 @@
3123+/*
3124+ * Copyright 2015 Canonical Ltd.
3125+ *
3126+ * This program is free software; you can redistribute it and/or modify
3127+ * it under the terms of the GNU Lesser General Public License as published by
3128+ * the Free Software Foundation; version 3.
3129+ *
3130+ * This program is distributed in the hope that it will be useful,
3131+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3132+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3133+ * GNU Lesser General Public License for more details.
3134+ *
3135+ * You should have received a copy of the GNU Lesser General Public License
3136+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3137+ */
3138+
3139+#ifndef UCABSTRACTBUTTON_H
3140+#define UCABSTRACTBUTTON_H
3141+
3142+#include "ucactionitem.h"
3143+
3144+class QQuickMouseArea;
3145+class UCAbstractButton : public UCActionItem
3146+{
3147+ Q_OBJECT
3148+ Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
3149+ Q_PROPERTY(bool hovered READ hovered NOTIFY hoveredChanged)
3150+
3151+ // internal, declared to support the deprecated ListItem module
3152+ Q_PROPERTY(bool __acceptEvents MEMBER m_acceptEvents)
3153+ Q_PROPERTY(QQuickMouseArea *__mouseArea READ privateMouseArea CONSTANT)
3154+public:
3155+ explicit UCAbstractButton(QQuickItem *parent = 0);
3156+
3157+ bool pressed() const;
3158+ bool hovered() const;
3159+
3160+ bool privateAcceptEvents() const;
3161+ void setPrivateAcceptEvents(bool accept);
3162+ QQuickMouseArea *privateMouseArea() const;
3163+
3164+protected:
3165+ void classBegin();
3166+ void componentComplete();
3167+ void keyPressEvent(QKeyEvent *key);
3168+
3169+Q_SIGNALS:
3170+ void pressedChanged();
3171+ void hoveredChanged();
3172+ void clicked();
3173+ void pressAndHold();
3174+
3175+protected Q_SLOTS:
3176+ void _q_mouseAreaClicked();
3177+ void _q_mouseAreaPressAndHold();
3178+
3179+protected:
3180+ QQuickMouseArea *m_mouseArea;
3181+ bool m_acceptEvents:1;
3182+
3183+ bool isPressAndHoldConnected();
3184+};
3185+
3186+#endif // UCABSTRACTBUTTON_H
3187
3188=== modified file 'src/Ubuntu/Components/plugin/ucaction.cpp'
3189--- src/Ubuntu/Components/plugin/ucaction.cpp 2015-07-03 19:16:56 +0000
3190+++ src/Ubuntu/Components/plugin/ucaction.cpp 2015-09-08 04:09:38 +0000
3191@@ -150,13 +150,12 @@
3192
3193 UCAction::UCAction(QObject *parent)
3194 : QObject(parent)
3195+ , m_itemHint(Q_NULLPTR)
3196+ , m_parameterType(None)
3197 , m_factoryIconSource(true)
3198 , m_enabled(true)
3199 , m_visible(true)
3200 , m_published(false)
3201- , m_itemHint(0)
3202- , m_parameterType(None)
3203- , m_shortcut(0)
3204 {
3205 generateName();
3206 }
3207@@ -288,7 +287,7 @@
3208 qmlInfo(this) << "Invalid shortcut: " << shortcut.toString();
3209
3210 m_shortcut = shortcut;
3211- Q_EMIT shortcutChanged(shortcut);
3212+ Q_EMIT shortcutChanged();
3213 }
3214
3215 bool UCAction::event(QEvent *event)
3216@@ -302,7 +301,8 @@
3217 return false;
3218 }
3219
3220- trigger();
3221+ // do not call trigger() directly but invoke, as it may get overridden in QML
3222+ metaObject()->invokeMethod(this, "trigger");
3223 return true;
3224 }
3225
3226
3227=== modified file 'src/Ubuntu/Components/plugin/ucaction.h'
3228--- src/Ubuntu/Components/plugin/ucaction.h 2015-07-07 13:57:50 +0000
3229+++ src/Ubuntu/Components/plugin/ucaction.h 2015-09-08 04:09:38 +0000
3230@@ -70,28 +70,29 @@
3231 void parameterTypeChanged();
3232 void iconSourceChanged();
3233 void visibleChanged();
3234- void shortcutChanged(const QVariant& shortcut);
3235+ void shortcutChanged();
3236 void triggered(const QVariant &value);
3237
3238 public Q_SLOTS:
3239 void trigger(const QVariant &value = QVariant());
3240
3241 private:
3242- bool m_factoryIconSource:1;
3243- bool m_enabled:1;
3244- bool m_visible:1;
3245- bool m_published:1;
3246- QQmlComponent *m_itemHint;
3247 QString m_name;
3248 QString m_text;
3249 QString m_iconName;
3250 QUrl m_iconSource;
3251 QString m_description;
3252 QString m_keywords;
3253+ QVariant m_shortcut;
3254+ QQmlComponent *m_itemHint;
3255 Type m_parameterType;
3256- QVariant m_shortcut;
3257+ bool m_factoryIconSource:1;
3258+ bool m_enabled:1;
3259+ bool m_visible:1;
3260+ bool m_published:1;
3261
3262 friend class UCActionContext;
3263+ friend class UCActionItem;
3264 friend class UCListItemPrivate;
3265 friend class UCListItemAttached;
3266 friend class UCListItemActionsPrivate;
3267
3268=== modified file 'src/Ubuntu/Components/plugin/ucactioncontext.cpp'
3269--- src/Ubuntu/Components/plugin/ucactioncontext.cpp 2015-07-09 17:55:03 +0000
3270+++ src/Ubuntu/Components/plugin/ucactioncontext.cpp 2015-09-08 04:09:38 +0000
3271@@ -104,6 +104,11 @@
3272 * sufficient to manage the active local context of the manager and no additional
3273 * calls are necessary to manually inactivate the other contexts.
3274 */
3275+bool UCActionContext::active()
3276+{
3277+ return m_active;
3278+}
3279+
3280 void UCActionContext::setActive(bool active)
3281 {
3282 if (m_active == active) {
3283@@ -114,7 +119,7 @@
3284 return;
3285 }
3286 m_active = active;
3287- Q_EMIT activeChanged(active);
3288+ Q_EMIT activeChanged();
3289 }
3290
3291 /*!
3292
3293=== modified file 'src/Ubuntu/Components/plugin/ucactioncontext.h'
3294--- src/Ubuntu/Components/plugin/ucactioncontext.h 2015-07-09 17:55:03 +0000
3295+++ src/Ubuntu/Components/plugin/ucactioncontext.h 2015-09-08 04:09:38 +0000
3296@@ -29,7 +29,7 @@
3297 Q_OBJECT
3298 Q_INTERFACES(QQmlParserStatus)
3299 Q_PROPERTY(QQmlListProperty<UCAction> actions READ actions)
3300- Q_PROPERTY(bool active MEMBER m_active WRITE setActive NOTIFY activeChanged)
3301+ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
3302 Q_CLASSINFO("DefaultProperty", "actions")
3303 public:
3304 explicit UCActionContext(QObject *parent = 0);
3305@@ -41,10 +41,11 @@
3306
3307 QQmlListProperty<UCAction> actions();
3308
3309+ bool active();
3310 void setActive(bool active);
3311
3312 Q_SIGNALS:
3313- void activeChanged(bool);
3314+ void activeChanged();
3315
3316 public Q_SLOTS:
3317 void addAction(UCAction *action);
3318
3319=== added file 'src/Ubuntu/Components/plugin/ucactionitem.cpp'
3320--- src/Ubuntu/Components/plugin/ucactionitem.cpp 1970-01-01 00:00:00 +0000
3321+++ src/Ubuntu/Components/plugin/ucactionitem.cpp 2015-09-08 04:09:38 +0000
3322@@ -0,0 +1,316 @@
3323+/*
3324+ * Copyright 2015 Canonical Ltd.
3325+ *
3326+ * This program is free software; you can redistribute it and/or modify
3327+ * it under the terms of the GNU Lesser General Public License as published by
3328+ * the Free Software Foundation; version 3.
3329+ *
3330+ * This program is distributed in the hope that it will be useful,
3331+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3332+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3333+ * GNU Lesser General Public License for more details.
3334+ *
3335+ * You should have received a copy of the GNU Lesser General Public License
3336+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3337+ */
3338+
3339+#include "ucactionitem.h"
3340+#include "ucaction.h"
3341+
3342+/*!
3343+ * \qmltype ActionItem
3344+ * \instantiates UCActionItem
3345+ * \inqmlmodule Ubuntu.Components 1.1
3346+ * \ingroup ubuntu
3347+ * \brief A visual representation of an Action. The API of ActionItem is a
3348+ * copy of the API of \l Action, with additional properties to define
3349+ * visual aspects of the ActionItem.
3350+ *
3351+ * If \l action is set, the values of the other properties will by default
3352+ * be identical to the \l Action's property values. Setting the other properties
3353+ * will override the properties copied from the \l Action.
3354+ */
3355+
3356+/*!
3357+ * \qmlsignal ActionItem::triggered(var value)
3358+ * Called when the actionItem is triggered.
3359+ */
3360+UCActionItem::UCActionItem(QQuickItem *parent)
3361+ : UCStyledItemBase(parent)
3362+ , m_action(Q_NULLPTR)
3363+ , m_flags(0)
3364+{
3365+ connect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged);
3366+ connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged);
3367+}
3368+
3369+void UCActionItem::componentComplete()
3370+{
3371+ UCStyledItemBase::componentComplete();
3372+ // make sure we connect to the right signals, so we detach and re-attach actions
3373+ // to make sure the SLOT macro picks up the custom trigger() slot
3374+ if (m_action) {
3375+ attachAction(false);
3376+ attachAction(true);
3377+ }
3378+}
3379+
3380+void UCActionItem::_q_visibleChanged()
3381+{
3382+ m_flags |= CustomVisible;
3383+ disconnect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged);
3384+}
3385+
3386+void UCActionItem::_q_enabledChanged()
3387+{
3388+ m_flags |= CustomEnabled;
3389+ disconnect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged);
3390+}
3391+
3392+// update visible property
3393+void UCActionItem::_q_updateVisible()
3394+{
3395+ bool visible = m_action ? m_action->m_visible : true;
3396+ setVisible(visible);
3397+ // reset flag and reconnect signal handler disconnected by the
3398+ m_flags &= ~CustomVisible;
3399+ if (m_action) {
3400+ connect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged);
3401+ }
3402+}
3403+
3404+// update enabled property
3405+void UCActionItem::_q_updateEnabled()
3406+{
3407+ bool enabled = m_action ? m_action->m_enabled : true;
3408+ setEnabled(enabled);
3409+ // reset flag and reconnect signal handler disconnected by the
3410+ m_flags &= ~CustomEnabled;
3411+ if (m_action) {
3412+ connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged);
3413+ }
3414+}
3415+
3416+void UCActionItem::updateProperties()
3417+{
3418+ if (!(m_flags & CustomText)) {
3419+ Q_EMIT textChanged();
3420+ }
3421+ if (!(m_flags & CustomIconSource)) {
3422+ Q_EMIT iconSourceChanged();
3423+ }
3424+ if (!(m_flags & CustomIconName)) {
3425+ Q_EMIT iconNameChanged();
3426+ }
3427+}
3428+
3429+void UCActionItem::attachAction(bool attach)
3430+{
3431+ if (attach) {
3432+ connect(this, SIGNAL(triggered(QVariant)),
3433+ m_action, SLOT(trigger(QVariant)), Qt::DirectConnection);
3434+ connect(m_action, &UCAction::visibleChanged,
3435+ this, &UCActionItem::_q_updateVisible, Qt::DirectConnection);
3436+ connect(m_action, &UCAction::enabledChanged,
3437+ this, &UCActionItem::_q_updateEnabled, Qt::DirectConnection);
3438+ if (!(m_flags & CustomText)) {
3439+ connect(m_action, &UCAction::textChanged,
3440+ this, &UCActionItem::textChanged, Qt::DirectConnection);
3441+ }
3442+ if (!(m_flags & CustomIconSource)) {
3443+ connect(m_action, &UCAction::iconSourceChanged,
3444+ this, &UCActionItem::iconSourceChanged, Qt::DirectConnection);
3445+ }
3446+ if (!(m_flags & CustomIconName)) {
3447+ connect(m_action, &UCAction::iconNameChanged,
3448+ this, &UCActionItem::iconNameChanged, Qt::DirectConnection);
3449+ }
3450+ } else {
3451+ disconnect(this, SIGNAL(triggered(QVariant)),
3452+ m_action, SLOT(trigger(QVariant)));
3453+ disconnect(m_action, &UCAction::visibleChanged,
3454+ this, &UCActionItem::_q_updateVisible);
3455+ disconnect(m_action, &UCAction::enabledChanged,
3456+ this, &UCActionItem::_q_updateEnabled);
3457+ if (!(m_flags & CustomText)) {
3458+ disconnect(m_action, &UCAction::textChanged,
3459+ this, &UCActionItem::textChanged);
3460+ }
3461+ if (!(m_flags & CustomIconSource)) {
3462+ disconnect(m_action, &UCAction::iconSourceChanged,
3463+ this, &UCActionItem::iconSourceChanged);
3464+ }
3465+ if (!(m_flags & CustomIconName)) {
3466+ disconnect(m_action, &UCAction::iconNameChanged,
3467+ this, &UCActionItem::iconNameChanged);
3468+ }
3469+ }
3470+}
3471+
3472+/*!
3473+ * \qmlproperty Action ActionItem::action
3474+ * The \l Action associated with this ActionItem. If action is set, the values
3475+ * of the \l Action properties are copied to the values of the ActionItem
3476+ * properties, unless those were previously overridden.
3477+ */
3478+void UCActionItem::setAction(UCAction *action)
3479+{
3480+ if (m_action == action) {
3481+ return;
3482+ }
3483+ if (m_action) {
3484+ attachAction(false);
3485+ }
3486+ m_action = action;
3487+ Q_EMIT actionChanged();
3488+
3489+ if (m_action) {
3490+ attachAction(true);
3491+ }
3492+ _q_updateVisible();
3493+ _q_updateEnabled();
3494+ updateProperties();
3495+}
3496+
3497+/*!
3498+ * \qmlproperty string ActionItem::text
3499+ * The title of the actionItem. Defaults to the \c action.text.
3500+ */
3501+QString UCActionItem::text()
3502+{
3503+ if (m_flags & CustomText) {
3504+ return m_text;
3505+ }
3506+ return m_action ? m_action->m_text : QString();
3507+}
3508+void UCActionItem::setText(const QString &text)
3509+{
3510+ if (m_text == text) {
3511+ return;
3512+ }
3513+ m_text = text;
3514+ if (m_action && !(m_flags & CustomText)) {
3515+ // disconnect change signal from Action
3516+ disconnect(m_action, &UCAction::textChanged,
3517+ this, &UCActionItem::textChanged);
3518+ }
3519+ m_flags |= CustomText;
3520+ Q_EMIT textChanged();
3521+}
3522+void UCActionItem::resetText()
3523+{
3524+ m_text.clear();
3525+ m_flags &= ~CustomText;
3526+ if (m_action) {
3527+ // re-connect change signal from Action
3528+ connect(m_action, &UCAction::textChanged,
3529+ this, &UCActionItem::textChanged, Qt::DirectConnection);
3530+ }
3531+ Q_EMIT textChanged();
3532+}
3533+
3534+/*!
3535+ * \qmlproperty url ActionItem::iconSource
3536+ * The image associated with the ActionItem. Defaults to \c action.iconSource.
3537+ *
3538+ * This is the URL of any image file. If both iconSource and \l iconName are defined,
3539+ * \l iconName will be ignored.
3540+ */
3541+QUrl UCActionItem::iconSource()
3542+{
3543+ if (m_flags & CustomIconSource) {
3544+ return m_iconSource;
3545+ }
3546+ if (m_action) {
3547+ return m_action->m_iconSource;
3548+ }
3549+ return !iconName().isEmpty() ? QUrl(QString("image://theme/%1").arg(iconName())) : QUrl();
3550+}
3551+void UCActionItem::setIconSource(const QUrl &iconSource)
3552+{
3553+ if (m_iconSource == iconSource) {
3554+ return;
3555+ }
3556+ m_iconSource = iconSource;
3557+ if (m_action && !(m_flags & CustomIconSource)) {
3558+ // disconnect change signal from Action
3559+ disconnect(m_action, &UCAction::iconSourceChanged,
3560+ this, &UCActionItem::iconSourceChanged);
3561+ }
3562+ m_flags |= CustomIconSource;
3563+ Q_EMIT iconSourceChanged();
3564+}
3565+void UCActionItem::resetIconSource()
3566+{
3567+ m_iconSource.clear();
3568+ m_flags &= ~CustomIconSource;
3569+ if (m_action) {
3570+ // re-connect change signal from Action
3571+ connect(m_action, &UCAction::iconSourceChanged,
3572+ this, &UCActionItem::iconSourceChanged, Qt::DirectConnection);
3573+ }
3574+ Q_EMIT iconSourceChanged();
3575+}
3576+
3577+/*!
3578+ * \qmlproperty string ActionItem::iconName
3579+ * The icon associated with the actionItem in the suru icon theme. Defaults to
3580+ * \c action.iconName.
3581+ *
3582+ * \note The complete list of icons available in Ubuntu is not published yet.
3583+ * For now please refer to the folders where the icon themes are installed:
3584+ * \list
3585+ * \li Ubuntu Touch: \l file:/usr/share/icons/suru
3586+ * \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark
3587+ * \endlist
3588+ * These 2 separate icon themes will be merged soon.
3589+ *
3590+ * If both \l iconSource and iconName are defined, iconName will be ignored.
3591+ */
3592+QString UCActionItem::iconName()
3593+{
3594+ if (m_flags & CustomIconName) {
3595+ return m_iconName;
3596+ }
3597+ return m_action ? m_action->m_iconName : QString();
3598+}
3599+void UCActionItem::setIconName(const QString &iconName)
3600+{
3601+ if (m_iconName == iconName) {
3602+ return;
3603+ }
3604+ m_iconName = iconName;
3605+ if (m_action && !(m_flags & CustomIconName)) {
3606+ // disconnect change signal from Action
3607+ disconnect(m_action, &UCAction::iconNameChanged,
3608+ this, &UCActionItem::iconNameChanged);
3609+ }
3610+ m_flags |= CustomIconName;
3611+ Q_EMIT iconNameChanged();
3612+ // also sync iconSource if that is not a custom one or taken from action
3613+ if (!m_action || (m_flags & CustomIconSource)) {
3614+ Q_EMIT iconSourceChanged();
3615+ }
3616+}
3617+void UCActionItem::resetIconName()
3618+{
3619+ m_iconName.clear();
3620+ m_flags &= ~CustomIconName;
3621+ if (m_action) {
3622+ // re-connect change signal from Action
3623+ connect(m_action, &UCAction::iconNameChanged,
3624+ this, &UCActionItem::iconNameChanged, Qt::DirectConnection);
3625+ }
3626+ Q_EMIT iconNameChanged();
3627+}
3628+
3629+/*!
3630+ * \qmlmethod void ActionItem::trigger(var value)
3631+ * Trigger this action item if it is enabled.
3632+ */
3633+void UCActionItem::trigger(const QVariant &value)
3634+{
3635+ if (isEnabled()) {
3636+ Q_EMIT triggered(value);
3637+ }
3638+}
3639
3640=== added file 'src/Ubuntu/Components/plugin/ucactionitem.h'
3641--- src/Ubuntu/Components/plugin/ucactionitem.h 1970-01-01 00:00:00 +0000
3642+++ src/Ubuntu/Components/plugin/ucactionitem.h 2015-09-08 04:09:38 +0000
3643@@ -0,0 +1,79 @@
3644+/*
3645+ * Copyright 2015 Canonical Ltd.
3646+ *
3647+ * This program is free software; you can redistribute it and/or modify
3648+ * it under the terms of the GNU Lesser General Public License as published by
3649+ * the Free Software Foundation; version 3.
3650+ *
3651+ * This program is distributed in the hope that it will be useful,
3652+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3653+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3654+ * GNU Lesser General Public License for more details.
3655+ *
3656+ * You should have received a copy of the GNU Lesser General Public License
3657+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3658+ */
3659+#ifndef UCACTIONITEM_H
3660+#define UCACTIONITEM_H
3661+
3662+#include "ucstyleditembase.h"
3663+
3664+class UCAction;
3665+class UCActionItem : public UCStyledItemBase
3666+{
3667+ Q_OBJECT
3668+ Q_PROPERTY(UCAction *action MEMBER m_action WRITE setAction NOTIFY actionChanged FINAL)
3669+ Q_PROPERTY(QString text READ text WRITE setText RESET resetText NOTIFY textChanged)
3670+ Q_PROPERTY(QUrl iconSource READ iconSource WRITE setIconSource RESET resetIconSource NOTIFY iconSourceChanged)
3671+ Q_PROPERTY(QString iconName READ iconName WRITE setIconName RESET resetIconName NOTIFY iconNameChanged)
3672+public:
3673+ explicit UCActionItem(QQuickItem *parent = 0);
3674+
3675+ void setAction(UCAction *action);
3676+ QString text();
3677+ void setText(const QString &text);
3678+ void resetText();
3679+ QUrl iconSource();
3680+ void setIconSource(const QUrl &iconSource);
3681+ void resetIconSource();
3682+ QString iconName();
3683+ void setIconName(const QString &iconName);
3684+ void resetIconName();
3685+
3686+Q_SIGNALS:
3687+ void actionChanged();
3688+ void textChanged();
3689+ void iconSourceChanged();
3690+ void iconNameChanged();
3691+ void triggered(const QVariant &value);
3692+
3693+public Q_SLOTS:
3694+ void trigger(const QVariant &value = QVariant());
3695+
3696+protected Q_SLOTS:
3697+ void _q_visibleChanged();
3698+ void _q_enabledChanged();
3699+ void _q_updateVisible();
3700+ void _q_updateEnabled();
3701+
3702+protected:
3703+ enum {
3704+ CustomText = 0x01,
3705+ CustomIconSource = 0x02,
3706+ CustomIconName = 0x04,
3707+ CustomVisible = 0x40,
3708+ CustomEnabled = 0x80
3709+ };
3710+ QString m_text;
3711+ QString m_iconName;
3712+ QUrl m_iconSource;
3713+ UCAction *m_action;
3714+ quint8 m_flags;
3715+
3716+ void componentComplete();
3717+
3718+ void updateProperties();
3719+ void attachAction(bool attach);
3720+};
3721+
3722+#endif // UCACTIONITEM_H
3723
3724=== added file 'src/Ubuntu/Components/plugin/uchaptics.cpp'
3725--- src/Ubuntu/Components/plugin/uchaptics.cpp 1970-01-01 00:00:00 +0000
3726+++ src/Ubuntu/Components/plugin/uchaptics.cpp 2015-09-08 04:09:38 +0000
3727@@ -0,0 +1,179 @@
3728+/*
3729+ * Copyright 2015 Canonical Ltd.
3730+ *
3731+ * This program is free software; you can redistribute it and/or modify
3732+ * it under the terms of the GNU Lesser General Public License as published by
3733+ * the Free Software Foundation; version 3.
3734+ *
3735+ * This program is distributed in the hope that it will be useful,
3736+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3737+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3738+ * GNU Lesser General Public License for more details.
3739+ *
3740+ * You should have received a copy of the GNU Lesser General Public License
3741+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3742+ */
3743+
3744+#include "uchaptics.h"
3745+#include "plugin.h"
3746+#include <QtQml/QQmlComponent>
3747+#include <QtCore/QUrl>
3748+#include <QDebug>
3749+
3750+/*!
3751+ \qmltype Haptics
3752+ \instantiates UCHaptics
3753+ \inqmlmodule Ubuntu.Components 1.1
3754+ \ingroup ubuntu-services
3755+ \brief Singleton defining the haptics feedback used in components, where execution
3756+ of the feedback is controlled by the system settings.
3757+
3758+ Supports global feedback as well as custom feedback. Global feedback can be
3759+ configured through its properties, and \l play function will play the default
3760+ configuration, or a custom one if parameter is given.
3761+
3762+ Example of using Haptics:
3763+ \qml
3764+ import QtQuick 2.4
3765+ import Ubuntu.Components 1.3
3766+
3767+ Item {
3768+ implicitWidth: units.gu(20)
3769+ implicitHeight: units.gu(5)
3770+
3771+ Label {
3772+ text: "Press me"
3773+ anchors.fill: parent
3774+ horizontalAlignment: Text.AlignHCenter
3775+ verticalAlignment: Text.AlignVCenter
3776+ }
3777+ MouseArea {
3778+ anchors.fill: parent
3779+ onClicked: Haptics.play()
3780+ }
3781+ }
3782+ \endqml
3783+
3784+ Custom effects can be played as follows:
3785+ \qml
3786+ import QtQuick 2.4
3787+ import Ubuntu.Components 1.3
3788+
3789+ Item {
3790+ implicitWidth: units.gu(20)
3791+ implicitHeight: units.gu(5)
3792+
3793+ Label {
3794+ text: "Press me"
3795+ anchors.fill: parent
3796+ horizontalAlignment: Text.AlignHCenter
3797+ verticalAlignment: Text.AlignVCenter
3798+ }
3799+ MouseArea {
3800+ anchors.fill: parent
3801+ onClicked: Haptics.play({duration: 25, attackIntensity: 0.7})
3802+ }
3803+ }
3804+ \endqml
3805+
3806+ \note Though the \l effect property exposes \c start, \c stop and \c pause
3807+ functions, use those only if you want to have feedback independent from what the
3808+ system setting is.
3809+ */
3810+
3811+UCHaptics::UCHaptics(QObject *parent)
3812+ : QObject(parent)
3813+{
3814+ connect(&HapticsProxy::instance(), &HapticsProxy::enabledChanged,
3815+ this, &UCHaptics::enabledChanged);
3816+}
3817+
3818+/*!
3819+ \qmlproperty bool Haptics::enabled
3820+ \readonly
3821+ The property specifies whether the haptics feedback is enabled or not by the system.
3822+ */
3823+bool UCHaptics::enabled() const
3824+{
3825+ return HapticsProxy::instance().enabled();
3826+}
3827+
3828+/*!
3829+ \qmlproperty HapticsEffect Haptics::effect
3830+ \readonly
3831+ The property defines the settings of the haptics effect used by the component.
3832+ The default setting is a haptics effect with a duration of 10 milliseconds
3833+ with an intensity of 1.0, having fading time of 50 millisecods and fading
3834+ intensity 0.0, and attack time of 50 milliseconds and with an intensity of
3835+ 0.0.
3836+ */
3837+QObject *UCHaptics::effect() const
3838+{
3839+ return HapticsProxy::instance().effect();
3840+}
3841+
3842+/*!
3843+ \qmlmethod void Haptics::play(var customEffect)
3844+ The function plays the feedback with the configuration specified in \l effect
3845+ if no parameter is given. Custom effect can be played by specifying the effect
3846+ properties in a JSON object in \c customEffect.
3847+
3848+ The function will exit unconditionaly if playing the effects is blocked by
3849+ system settings.
3850+
3851+ The function will not stop any ongoing haptics effect played, if that one
3852+ was a default haptics effect. In case of custom effects, the previous effect
3853+ will be stopped, and settings will be restored before the new haptics will
3854+ be played. The custom settings properties (the ones which are required to
3855+ be different from the ones defined in the \l effect) must be specified in
3856+ the parameter in a JSON object.
3857+ */
3858+void UCHaptics::play(const QVariant &customEffect)
3859+{
3860+ HapticsProxy::instance().play(customEffect);
3861+}
3862+
3863+/*********************************************************
3864+ * Proxy implementation
3865+ */
3866+bool HapticsProxy::enabled()
3867+{
3868+ initialize();
3869+ return (m_proxyObject) ? m_proxyObject->property("enabled").toBool() : false;
3870+}
3871+
3872+QObject *HapticsProxy::effect()
3873+{
3874+ initialize();
3875+ return (m_proxyObject) ? m_proxyObject->property("effect").value<QObject*>() : Q_NULLPTR;
3876+}
3877+
3878+void HapticsProxy::initialize()
3879+{
3880+ if (!m_engine || m_proxyObject) {
3881+ return;
3882+ }
3883+ // load haptics proxy from file system/qrc
3884+ QUrl path = UbuntuComponentsPlugin::pluginUrl().resolved(QUrl("1.1/Haptics.qml"));
3885+ QQmlComponent component(m_engine, path, QQmlComponent::PreferSynchronous);
3886+ if (!component.isError()) {
3887+ m_proxyObject = component.create();
3888+ if (m_proxyObject) {
3889+ connect(m_proxyObject, SIGNAL(enabledChanged()), this, SIGNAL(enabledChanged()));
3890+ }
3891+ } else {
3892+ qWarning() << qPrintable(component.errorString());
3893+ }
3894+}
3895+
3896+void HapticsProxy::play(const QVariant &customEffect)
3897+{
3898+ if (!m_engine) {
3899+ qWarning() << "Engine not specified, haptics won't play";
3900+ }
3901+ initialize();
3902+ if (m_proxyObject) {
3903+ // invoke play function
3904+ m_proxyObject->metaObject()->invokeMethod(m_proxyObject, "play", Q_ARG(QVariant, customEffect));
3905+ }
3906+}
3907
3908=== added file 'src/Ubuntu/Components/plugin/uchaptics.h'
3909--- src/Ubuntu/Components/plugin/uchaptics.h 1970-01-01 00:00:00 +0000
3910+++ src/Ubuntu/Components/plugin/uchaptics.h 2015-09-08 04:09:38 +0000
3911@@ -0,0 +1,78 @@
3912+/*
3913+ * Copyright 2015 Canonical Ltd.
3914+ *
3915+ * This program is free software; you can redistribute it and/or modify
3916+ * it under the terms of the GNU Lesser General Public License as published by
3917+ * the Free Software Foundation; version 3.
3918+ *
3919+ * This program is distributed in the hope that it will be useful,
3920+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3921+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3922+ * GNU Lesser General Public License for more details.
3923+ *
3924+ * You should have received a copy of the GNU Lesser General Public License
3925+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3926+ */
3927+
3928+#ifndef UCHAPTICS_H
3929+#define UCHAPTICS_H
3930+
3931+#include <QtCore/QObject>
3932+#include <QtCore/QVariant>
3933+
3934+class UCHaptics : public QObject
3935+{
3936+ Q_OBJECT
3937+ Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
3938+ Q_PROPERTY(QObject *effect READ effect CONSTANT)
3939+public:
3940+ explicit UCHaptics(QObject *parent = 0);
3941+
3942+ bool enabled() const;
3943+ QObject *effect() const;
3944+
3945+Q_SIGNALS:
3946+ void enabledChanged();
3947+
3948+public Q_SLOTS:
3949+ void play(const QVariant &customEffect = QVariant());
3950+};
3951+
3952+class QQmlEngine;
3953+class HapticsProxy : public QObject
3954+{
3955+ Q_OBJECT
3956+public:
3957+ explicit HapticsProxy(QObject *parent = 0)
3958+ : QObject(parent)
3959+ , m_proxyObject(Q_NULLPTR)
3960+ , m_engine(Q_NULLPTR)
3961+ {
3962+ }
3963+
3964+ static HapticsProxy &instance()
3965+ {
3966+ static HapticsProxy instance;
3967+ return instance;
3968+ }
3969+
3970+ void setEngine(QQmlEngine *engine)
3971+ {
3972+ m_engine = engine;
3973+ }
3974+
3975+ void initialize();
3976+
3977+ bool enabled();
3978+ QObject *effect();
3979+ void play(const QVariant &customEffect);
3980+
3981+Q_SIGNALS:
3982+ void enabledChanged();
3983+
3984+private:
3985+ QObject *m_proxyObject;
3986+ QQmlEngine *m_engine;
3987+};
3988+
3989+#endif // UCHAPTICS_H
3990
3991=== modified file 'src/Ubuntu/Components/plugin/uclistitem.cpp'
3992--- src/Ubuntu/Components/plugin/uclistitem.cpp 2015-07-30 13:27:32 +0000
3993+++ src/Ubuntu/Components/plugin/uclistitem.cpp 2015-09-08 04:09:38 +0000
3994@@ -200,6 +200,7 @@
3995 , leadingActions(0)
3996 , trailingActions(0)
3997 , mainAction(0)
3998+ , expansion(Q_NULLPTR)
3999 {
4000 }
4001 UCListItemPrivate::~UCListItemPrivate()
4002@@ -325,7 +326,7 @@
4003 bool UCListItemPrivate::loadStyleItem(bool animated)
4004 {
4005 // the style should be loaded only if one of the condition is satisfied
4006- if (!swiped && !selectMode() && !dragMode()) {
4007+ if (!swiped && !selectMode() && !dragMode() && !(expansion && expansion->expanded())) {
4008 return false;
4009 }
4010
4011@@ -339,6 +340,7 @@
4012 preStyleChanged();
4013 return false;
4014 }
4015+ myStyle->updateFlickable(flickable);
4016 // bring the panels foreground
4017 styleItem->setZ(0);
4018 listItemStyle()->setAnimatePanels(true);
4019@@ -372,23 +374,13 @@
4020 (parentItem ? QQuickItemPrivate::get(parentItem)->childItems.indexOf(q) : -1);
4021 }
4022
4023-// returns true if the highlight is possible
4024-bool UCListItemPrivate::canHighlight(QMouseEvent *event)
4025+// returns true if the highlight is possible; the highlight is possible if the
4026+// list item has at least one action, leading/trailing actions set, onClicked
4027+// or onPressAndHold signal handlers set
4028+bool UCListItemPrivate::canHighlight()
4029 {
4030- // if automatic, the highlight should not happen if we clicked on an active component;
4031- // localPos is a position relative to ListItem which will give us a child from
4032- // from the original coordinates; therefore we must map the position to the contentItem
4033 Q_Q(UCListItem);
4034- QPointF myPos = q->mapToItem(contentItem, event->localPos());
4035- QQuickItem *child = contentItem->childAt(myPos.x(), myPos.y());
4036- bool activeComponent = child && (child->acceptedMouseButtons() & event->button()) &&
4037- child->isEnabled() && !qobject_cast<QQuickText*>(child);
4038- // do highlight if not pressed above the active component, and the component has either
4039- // action, leading or trailing actions list or at least an active child component declared
4040- QQuickMouseArea *ma = q->findChild<QQuickMouseArea*>();
4041- bool activeMouseArea = ma && ma->isEnabled();
4042- return !activeComponent && (isClickedConnected() || isPressAndHoldConnected() ||
4043- mainAction || leadingActions || trailingActions || activeMouseArea);
4044+ return (isClickedConnected() || isPressAndHoldConnected() || mainAction || leadingActions || trailingActions);
4045 }
4046
4047 // set highlighted flag and update contentItem
4048@@ -876,8 +868,74 @@
4049 *
4050 * \sa ViewItems::dragMode, ViewItems::dragUpdated
4051 *
4052+ * \section2 Expansion
4053+ * Since Ubuntu.Components 1.3, ListItem supports expansion. ListItems declared
4054+ * in a view can expand exclusively, having leading and trailing panes locked
4055+ * when expanded and to be collapsed when tapping outside of the expanded area.
4056+ * The expansion is driven by the \l expansion group property, and the behavior
4057+ * by the \l ViewItems::expansionFlags and \l ViewItems::expandedIndices
4058+ * attached properties. Each ListItem which is required to expand should set a
4059+ * proper height in the \l expansion.height property, which should be bigger
4060+ * than the collapsed height of the ListItem is. The expansion itself is driven
4061+ * by the \l expansion.expanded property, which can be set freely depending on
4062+ * the use case, on click, on long press, etc.
4063+ *
4064+ * The default expansion behavior is set to be exclusive and locked, meaning
4065+ * there can be only one ListItem expanded within a view and neither leading
4066+ * nor trailing action panels cannot be swiped in. Expanding an other ListItem
4067+ * will collapse the previosuly expanded one. There can be cases when tapping
4068+ * outside of the expanded area of a ListItem we woudl need the expanded one
4069+ * to collapse automatically. This can be achieved by setting \c ViewItems.CollapseOnOutsidePress
4070+ * flag to \l ViewItems::expansionFlags. This flag will also turn on \c ViewItems.Exclusive
4071+ * flag, as tapping outside practicly forbids more than one item to be expanded
4072+ * at a time.
4073+ * \qml
4074+ * import QtQuick 2.4
4075+ * import Ubuntu.Components 1.3
4076+ *
4077+ * ListView {
4078+ * width: units.gu(40)
4079+ * height: units.gu(71)
4080+ * model: ListModel {
4081+ * Component.onCompleted: {
4082+ * for (var i = 0; i < 50; i++) {
4083+ * append({data: i});
4084+ * }
4085+ * }
4086+ * }
4087+ * ViewItems.expansionFlags: ViewItems.CollapseOnOutsidePress
4088+ * delegate: ListItem {
4089+ * Label {
4090+ * text: "Model item #" + modelData
4091+ * }
4092+ * trailingActions: ListItemActions {
4093+ * actions: [
4094+ * Action {
4095+ * icon: "search"
4096+ * },
4097+ * Action {
4098+ * icon: "edit"
4099+ * },
4100+ * Action {
4101+ * icon: "copy"
4102+ * }
4103+ * ]
4104+ * }
4105+ * expansion.height: units.gu(15)
4106+ * onClicked: expansion.expanded = true
4107+ * }
4108+ * }
4109+ * \endqml
4110+ * The example above collapses the expanded item whenever it is tapped or mouse
4111+ * pressed outside of the expanded list item.
4112+ * \note Set 0 to \l ViewItems::expansionFlags if no restrictions on expanded items
4113+ * is required (i.e multiple expanded items are allowed, swiping leading/trailing
4114+ * actions when expanded).
4115+ * \note Do not bind \l expansion.height to the ListItem's height as is will cause
4116+ * binding loops.
4117+ *
4118 * \section2 Note on styling
4119- * ListItem's styling differs from the other component sstyling, as ListItem loads
4120+ * ListItem's styling differs from the other components styling, as ListItem loads
4121 * the style only when either of the leadin/trailing panels are swiped, or when the
4122 * item enters in select- or drag mode. The component does not assume any visuals
4123 * to be present in the style.
4124@@ -914,6 +972,11 @@
4125 {
4126 }
4127
4128+QObject *UCListItem::attachedViewItems(QObject *object, bool create)
4129+{
4130+ return qmlAttachedPropertiesObject<UCViewItemsAttached>(object, create);
4131+}
4132+
4133 void UCListItem::classBegin()
4134 {
4135 UCStyledItemBase::classBegin();
4136@@ -966,7 +1029,7 @@
4137 this, SLOT(_q_syncDragMode()));
4138
4139 // if selection or drag mode is on, initialize style, with animations turned off
4140- if (d->parentAttached->selectMode() || d->parentAttached->dragMode()) {
4141+ if (d->parentAttached->selectMode() || d->parentAttached->dragMode() || (d->expansion && d->expansion->expanded())) {
4142 d->loadStyleItem(false);
4143 }
4144 // set the object name for testing purposes
4145@@ -996,10 +1059,10 @@
4146 QQuickItem *parentAttachee = data.item;
4147 if (d->flickable && d->flickable->inherits("QQuickListView")) {
4148 // attach to ListView
4149- d->parentAttached = static_cast<UCViewItemsAttached*>(qmlAttachedPropertiesObject<UCViewItemsAttached>(d->flickable));
4150+ d->parentAttached = static_cast<UCViewItemsAttached*>(attachedViewItems(d->flickable, true));
4151 parentAttachee = d->flickable;
4152 } else if (data.item) {
4153- d->parentAttached = static_cast<UCViewItemsAttached*>(qmlAttachedPropertiesObject<UCViewItemsAttached>(data.item));
4154+ d->parentAttached = static_cast<UCViewItemsAttached*>(attachedViewItems(data.item, true));
4155 } else {
4156 // mark as not ready, so no action should be performed which depends on readyness
4157 d->ready = false;
4158@@ -1007,6 +1070,11 @@
4159 d->parentAttached = 0;
4160 }
4161
4162+ if (d->styleItem) {
4163+ UCListItemStyle * myStyle = static_cast<UCListItemStyle*>(d->styleItem);
4164+ myStyle->updateFlickable(d->flickable);
4165+ }
4166+
4167 if (parentAttachee) {
4168 QObject::connect(parentAttachee, SIGNAL(widthChanged()), this, SLOT(_q_updateSize()), Qt::DirectConnection);
4169 // update size
4170@@ -1081,7 +1149,7 @@
4171 // while moving, we cannot select any items
4172 return;
4173 }
4174- if (d->canHighlight(event) && !d->highlighted && event->button() == Qt::LeftButton) {
4175+ if (d->canHighlight() && !d->highlighted && event->button() == Qt::LeftButton) {
4176 d->grabLeftButtonEvents(event);
4177 }
4178 // accept the event so we get the rest of the events as well
4179@@ -1194,7 +1262,7 @@
4180 Q_D(UCListItem);
4181 UCStyledItemBase::mouseMoveEvent(event);
4182
4183- if (d->selectMode() || d->dragMode()) {
4184+ if (d->selectMode() || d->dragMode() || (d->expansion && d->expansion->expandedLocked())) {
4185 // no move is allowed while selectable mode is on
4186 return;
4187 }
4188@@ -1672,4 +1740,48 @@
4189 d->defaultThemeVersion = BUILD_VERSION(1, 3);
4190 }
4191
4192+QObject *UCListItem13::attachedViewItems(QObject *object, bool create)
4193+{
4194+ return qmlAttachedPropertiesObject<UCViewItemsAttached13>(object, create);
4195+}
4196+
4197+void UCListItem13::itemChange(ItemChange change, const ItemChangeData &data)
4198+{
4199+ UCListItem::itemChange(change, data);
4200+
4201+ Q_D(UCListItem);
4202+ // ViewItems drives expansion
4203+ if (d->parentAttached) {
4204+ connect(d->parentAttached.data(), SIGNAL(expandedIndicesChanged(QList<int>)),
4205+ this, SLOT(_q_updateExpansion(QList<int>)), Qt::UniqueConnection);
4206+ }
4207+}
4208+
4209+/*!
4210+ * \qmlpropertygroup ::ListItem::expansion
4211+ * \qmlproperty bool ListItem::expansion.expanded
4212+ * \qmlproperty real ListItem::expansion.height
4213+ * \since Ubuntu.Components 1.3
4214+ * The group drefines the expansion state of the ListItem.
4215+ */
4216+UCListItemExpansion *UCListItem13::expansion()
4217+{
4218+ Q_D(UCListItem);
4219+ if (!d->expansion) {
4220+ d->expansion = new UCListItemExpansion(this);
4221+ }
4222+ return d->expansion;
4223+}
4224+
4225+void UCListItem13::_q_updateExpansion(const QList<int> &indices)
4226+{
4227+ Q_UNUSED(indices);
4228+ Q_D(UCListItem);
4229+ Q_EMIT expansion()->expandedChanged();
4230+ // make sure the style is loaded
4231+ if (indices.contains(d->index())) {
4232+ d->loadStyleItem();
4233+ }
4234+}
4235+
4236 #include "moc_uclistitem.cpp"
4237
4238=== modified file 'src/Ubuntu/Components/plugin/uclistitem.h'
4239--- src/Ubuntu/Components/plugin/uclistitem.h 2015-07-28 19:29:19 +0000
4240+++ src/Ubuntu/Components/plugin/uclistitem.h 2015-09-08 04:09:38 +0000
4241@@ -62,6 +62,7 @@
4242 void resetHighlightColor();
4243
4244 protected:
4245+ virtual QObject *attachedViewItems(QObject *object, bool create);
4246 void classBegin();
4247 void componentComplete();
4248 QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data);
4249@@ -109,17 +110,24 @@
4250 Q_PRIVATE_SLOT(d_func(), void _q_syncDragMode())
4251 };
4252
4253+class UCListItemExpansion;
4254 class UCListItem13 : public UCListItem
4255 {
4256 Q_OBJECT
4257+ Q_PROPERTY(UCListItemExpansion* expansion READ expansion CONSTANT)
4258 protected:
4259+ virtual QObject *attachedViewItems(QObject *object, bool create);
4260+ void itemChange(ItemChange change, const ItemChangeData &data);
4261 void mousePressEvent(QMouseEvent *event);
4262 void mouseReleaseEvent(QMouseEvent *event);
4263 private:
4264+ Q_SLOT void _q_updateExpansion(const QList<int> &indices);
4265 bool shouldShowContextMenu(QMouseEvent *event);
4266 void popoverClosed();
4267 public:
4268 explicit UCListItem13(QQuickItem *parent = 0);
4269+
4270+ UCListItemExpansion *expansion();
4271 };
4272
4273 class UCListItemDividerPrivate;
4274@@ -158,8 +166,15 @@
4275 Q_PROPERTY(bool selectMode READ selectMode WRITE setSelectMode NOTIFY selectModeChanged)
4276 Q_PROPERTY(QList<int> selectedIndices READ selectedIndices WRITE setSelectedIndices NOTIFY selectedIndicesChanged)
4277 Q_PROPERTY(bool dragMode READ dragMode WRITE setDragMode NOTIFY dragModeChanged)
4278+ Q_ENUMS(ExpansionFlag)
4279 public:
4280- explicit UCViewItemsAttached(QObject *owner);
4281+ enum ExpansionFlag {
4282+ Exclusive = 0x01,
4283+ UnlockExpanded = 0x02,
4284+ CollapseOnOutsidePress = Exclusive | 0x04
4285+ };
4286+ Q_DECLARE_FLAGS(ExpansionFlags, ExpansionFlag)
4287+ explicit UCViewItemsAttached(QObject *owner = 0);
4288 ~UCViewItemsAttached();
4289
4290 static UCViewItemsAttached *qmlAttachedProperties(QObject *owner);
4291@@ -191,8 +206,68 @@
4292 private:
4293 Q_DECLARE_PRIVATE(UCViewItemsAttached)
4294 };
4295+Q_DECLARE_OPERATORS_FOR_FLAGS(UCViewItemsAttached::ExpansionFlags)
4296 QML_DECLARE_TYPEINFO(UCViewItemsAttached, QML_HAS_ATTACHED_PROPERTIES)
4297
4298+// FIXME keep the 1.3 properties in a separate class, workaround for bug
4299+// https://bugs.launchpad.net/ubuntu/+source/qtdeclarative-opensource-src/+bug/1389721
4300+// enums and flag are added to UCViewItemsAttached like normal
4301+class UCViewItemsAttached13 : public UCViewItemsAttached
4302+{
4303+ Q_OBJECT
4304+ Q_PROPERTY(QList<int> expandedIndices READ expandedIndices WRITE setExpandedIndices NOTIFY expandedIndicesChanged)
4305+ Q_PROPERTY(int expansionFlags READ expansionFlags WRITE setExpansionFlags NOTIFY expansionFlagsChanged)
4306+public:
4307+ explicit UCViewItemsAttached13(QObject *owner = 0);
4308+ static UCViewItemsAttached13 *qmlAttachedProperties(QObject *owner);
4309+
4310+ QList<int> expandedIndices() const;
4311+ void setExpandedIndices(QList<int> indices);
4312+ int expansionFlags() const;
4313+ void setExpansionFlags(int flags);
4314+
4315+Q_SIGNALS:
4316+ void expandedIndicesChanged(const QList<int> &indices);
4317+ void expansionFlagsChanged();
4318+
4319+private:
4320+ UCViewItemsAttachedPrivate *d_ptr;
4321+ Q_DECLARE_PRIVATE_D(d_ptr, UCViewItemsAttached)
4322+};
4323+QML_DECLARE_TYPEINFO(UCViewItemsAttached13, QML_HAS_ATTACHED_PROPERTIES)
4324+
4325+class UCListItemExpansion : public QObject
4326+{
4327+ Q_OBJECT
4328+ Q_PROPERTY(bool expanded READ expanded WRITE setExpanded NOTIFY expandedChanged)
4329+ Q_PROPERTY(qreal height MEMBER m_height WRITE setHeight NOTIFY heightChanged)
4330+public:
4331+ explicit UCListItemExpansion(QObject *parent = 0);
4332+
4333+ bool expandedLocked();
4334+ void enableClickFiltering(bool enable);
4335+
4336+ bool expanded();
4337+ void setExpanded(bool expanded);
4338+ void setHeight(qreal height);
4339+
4340+Q_SIGNALS:
4341+ void expandedChanged();
4342+ void heightChanged();
4343+
4344+protected:
4345+ bool eventFilter(QObject *, QEvent *);
4346+
4347+private:
4348+ UCListItem13 *m_listItem;
4349+ qreal m_height;
4350+ bool m_filtering:1;
4351+
4352+ friend class UCListItem;
4353+ friend class UCListItem13;
4354+ friend class UCListItemPrivate;
4355+};
4356+
4357 class UCDragEvent : public QObject
4358 {
4359 Q_OBJECT
4360
4361=== modified file 'src/Ubuntu/Components/plugin/uclistitem_p.h'
4362--- src/Ubuntu/Components/plugin/uclistitem_p.h 2015-07-30 13:27:32 +0000
4363+++ src/Ubuntu/Components/plugin/uclistitem_p.h 2015-09-08 04:09:38 +0000
4364@@ -60,7 +60,7 @@
4365 void _q_syncSelectMode();
4366 void _q_syncDragMode();
4367 int index();
4368- bool canHighlight(QMouseEvent *event);
4369+ bool canHighlight();
4370 void setHighlighted(bool pressed);
4371 void listenToRebind(bool listen);
4372 void lockContentItem(bool lock);
4373@@ -95,6 +95,7 @@
4374 UCListItemActions *leadingActions;
4375 UCListItemActions *trailingActions;
4376 UCAction *mainAction;
4377+ UCListItemExpansion *expansion;
4378
4379 // getters/setters
4380 QQmlListProperty<QObject> data();
4381@@ -147,17 +148,25 @@
4382 bool isDragUpdatedConnected();
4383 void updateSelectedIndices(int fromIndex, int toIndex);
4384
4385+ // expansion
4386+ void expand(int index, UCListItem13 *listItem, bool emitChangeSignal = true);
4387+ void collapse(int index, bool emitChangeSignal = true);
4388+ void collapseAll();
4389+ void toggleExpansionFlags(bool enable);
4390+
4391+ QSet<int> selectedList;
4392+ QMap<int, QPointer<UCListItem13> > expansionList;
4393+ QList< QPointer<QQuickFlickable> > flickables;
4394+ QList< PropertyChange* > changes;
4395+ QPointer<UCListItem> boundItem;
4396+ QPointer<UCListItem> disablerItem;
4397 QQuickFlickable *listView;
4398 ListItemDragArea *dragArea;
4399+ UCViewItemsAttached::ExpansionFlags expansionFlags;
4400 bool globalDisabled:1;
4401 bool selectable:1;
4402 bool draggable:1;
4403 bool ready:1;
4404- QSet<int> selectedList;
4405- QList< QPointer<QQuickFlickable> > flickables;
4406- QList< PropertyChange* > changes;
4407- QPointer<UCListItem> boundItem;
4408- QPointer<UCListItem> disablerItem;
4409 };
4410
4411 #endif // UCVIEWITEM_P_H
4412
4413=== modified file 'src/Ubuntu/Components/plugin/uclistitemstyle.cpp'
4414--- src/Ubuntu/Components/plugin/uclistitemstyle.cpp 2015-04-13 13:42:03 +0000
4415+++ src/Ubuntu/Components/plugin/uclistitemstyle.cpp 2015-09-08 04:09:38 +0000
4416@@ -21,6 +21,7 @@
4417 #include <QtQml/QQmlContext>
4418 #include <QtQml/QQmlInfo>
4419 #include <QtQuick/private/qquickanimation_p.h>
4420+#include <QtQuick/private/qquickflickable_p.h>
4421
4422 /*!
4423 * \qmltype ListItemStyle
4424@@ -41,6 +42,7 @@
4425 , m_snapAnimation(0)
4426 , m_dropAnimation(0)
4427 , m_dragPanel(0)
4428+ , m_flickable(Q_NULLPTR)
4429 , m_animatePanels(true)
4430 {
4431 }
4432@@ -54,21 +56,29 @@
4433 setAnimatePanels(context->contextProperty("animated").toBool());
4434 }
4435 m_listItem = qmlContext(this)->contextProperty("styledItem").value<UCListItem*>();
4436+ // get the flickable value
4437+ if (m_listItem) {
4438+ m_flickable = UCListItemPrivate::get(m_listItem)->flickable.data();
4439+ }
4440 }
4441
4442 void UCListItemStyle::componentComplete()
4443 {
4444 QQuickItem::componentComplete();
4445
4446- // look for overridden slots
4447- for (int i = metaObject()->methodOffset(); i < metaObject()->methodCount(); i++) {
4448- const QMetaMethod method = metaObject()->method(i);
4449- if (method.name() == QByteArrayLiteral("swipeEvent")) {
4450- m_swipeEvent = method;
4451- } else if (method.name() == QByteArrayLiteral("rebound")) {
4452- m_rebound = method;
4453- }
4454- }
4455+ // look for overridden slots, indexOfMethod returns th elast index of the overridden method
4456+ m_rebound = metaObject()->method(metaObject()->indexOfMethod("rebound()"));
4457+ m_swipeEvent = metaObject()->method(metaObject()->indexOfMethod("swipeEvent(QVariant)"));
4458+// qDebug() << m_rebound.isValid() << m_swipeEvent.isValid();
4459+// for (int i = metaObject()->methodOffset(); i < metaObject()->methodCount(); i++) {
4460+// const QMetaMethod method = metaObject()->method(i);
4461+// if (method.name() == QByteArrayLiteral("swipeEvent")) {
4462+// qDebug() << method.methodSignature();
4463+// m_swipeEvent = method;
4464+// } else if (method.name() == QByteArrayLiteral("rebound")) {
4465+// m_rebound = method;
4466+// }
4467+// }
4468
4469 // connect snapAnimation's stopped() and the owning ListItem's contentMovementeEnded() signals
4470 if (m_listItem && m_snapAnimation) {
4471@@ -92,6 +102,25 @@
4472 }
4473
4474 /*!
4475+ * \qmlproperty Flickable ListItemStyle::flickable
4476+ * \readonly
4477+ * \since Ubuntu.Components.Styles 1.3
4478+ * The property holds the Flickable (or ListView) holding the ListItem styled.
4479+ */
4480+QQuickFlickable *UCListItemStyle::flickable()
4481+{
4482+ return m_flickable;
4483+}
4484+void UCListItemStyle::updateFlickable(QQuickFlickable *flickable)
4485+{
4486+ if (m_flickable == flickable) {
4487+ return;
4488+ }
4489+ m_flickable = flickable;
4490+ Q_EMIT flickableChanged();
4491+}
4492+
4493+/*!
4494 * \qmlmethod ListItemStyle::swipeEvent(SwipeEvent event)
4495 * The function is called by the ListItem when a swipe action is performed, i.e.
4496 * when the swipe is started, the position is updated or the swipe ends. The
4497
4498=== modified file 'src/Ubuntu/Components/plugin/uclistitemstyle.h'
4499--- src/Ubuntu/Components/plugin/uclistitemstyle.h 2015-04-13 13:42:03 +0000
4500+++ src/Ubuntu/Components/plugin/uclistitemstyle.h 2015-09-08 04:09:38 +0000
4501@@ -62,6 +62,7 @@
4502 class QQuickPropertyAnimation;
4503 class QQuickBehavior;
4504 class UCListItem;
4505+class QQuickFlickable;
4506 class UCListItemStyle : public QQuickItem
4507 {
4508 Q_OBJECT
4509@@ -70,6 +71,7 @@
4510 Q_PROPERTY(bool animatePanels READ animatePanels NOTIFY animatePanelsChanged)
4511 Q_PROPERTY(QQuickItem *dragPanel MEMBER m_dragPanel NOTIFY dragPanelChanged)
4512 Q_PROPERTY(int listItemIndex READ index NOTIFY listItemIndexChanged FINAL REVISION 1)
4513+ Q_PROPERTY(QQuickFlickable *flickable READ flickable NOTIFY flickableChanged REVISION 1)
4514 public:
4515 explicit UCListItemStyle(QQuickItem *parent = 0);
4516
4517@@ -78,6 +80,8 @@
4518 bool animatePanels() const;
4519 void setAnimatePanels(bool animate);
4520 int index();
4521+ QQuickFlickable *flickable();
4522+ void updateFlickable(QQuickFlickable *flickable);
4523
4524 Q_SIGNALS:
4525 void snapAnimationChanged();
4526@@ -85,6 +89,7 @@
4527 void animatePanelsChanged();
4528 void dragPanelChanged();
4529 Q_REVISION(1) void listItemIndexChanged();
4530+ Q_REVISION(1) void flickableChanged();
4531
4532 public Q_SLOTS:
4533 void swipeEvent(UCSwipeEvent *event);
4534@@ -102,6 +107,7 @@
4535 QQuickAbstractAnimation *m_snapAnimation;
4536 QQuickPropertyAnimation *m_dropAnimation;
4537 QQuickItem *m_dragPanel;
4538+ QQuickFlickable *m_flickable;
4539 bool m_animatePanels:1;
4540
4541 friend class UCListItemPrivate;
4542
4543=== modified file 'src/Ubuntu/Components/plugin/ucqquickimageextension.cpp'
4544--- src/Ubuntu/Components/plugin/ucqquickimageextension.cpp 2014-11-24 13:14:35 +0000
4545+++ src/Ubuntu/Components/plugin/ucqquickimageextension.cpp 2015-09-08 04:09:38 +0000
4546@@ -19,6 +19,7 @@
4547 #include <QtCore/QFile>
4548 #include <QtCore/QFileInfo>
4549 #include <QtCore/QDir>
4550+#include <QtGui/QGuiApplication>
4551 #include <QtQuick/private/qquickimagebase_p.h>
4552
4553 #include "ucqquickimageextension.h"
4554@@ -78,8 +79,18 @@
4555 QString selectedFilePath = resolved.mid(separatorPosition+1);
4556
4557 if (scaleFactor == "1") {
4558- // No scaling. Just pass the file as is.
4559- m_image->setSource(QUrl::fromLocalFile(selectedFilePath));
4560+ if (qFuzzyCompare(qGuiApp->devicePixelRatio(), (qreal)1.0)
4561+ || selectedFilePath.endsWith(".svg") || selectedFilePath.endsWith(".svgz")) {
4562+ // No scaling necessary. Just pass the file as is.
4563+ m_image->setSource(QUrl::fromLocalFile(selectedFilePath));
4564+ } else {
4565+ // Need to scale the pixel-based image to suit the devicePixelRatio setting ourselves.
4566+ // If we let Qt do it, Qt will not choose the UITK-supported "@gu" scaled images.
4567+ m_image->setSource(QUrl("image://scaling/1/" + selectedFilePath));
4568+ // explicitly set the source size in the QQuickImageBase, this persuades it that the
4569+ // supplied image is suitable for the current devicePixelRatio.
4570+ m_image->setSourceSize(m_image->sourceSize());
4571+ }
4572 } else {
4573 // Prepend "image://scaling" for the image to be loaded by UCScalingImageProvider.
4574 if (!m_source.path().endsWith(".sci")) {
4575@@ -100,7 +111,13 @@
4576 rewrittenSciFile->setFileTemplate(QDir::tempPath() + QDir::separator() + "XXXXXX.sci");
4577 rewrittenSciFile->open();
4578 QTextStream output(rewrittenSciFile);
4579- rewritten = rewriteSciFile(selectedFilePath, scaleFactor, output);
4580+
4581+ if (qFuzzyCompare(qGuiApp->devicePixelRatio(), (qreal)1.0)) {
4582+ rewritten = rewriteSciFile(selectedFilePath, scaleFactor, output);
4583+ } else {
4584+ QString scaleFactorInDevicePixels = QString::number(scaleFactor.toFloat() / qGuiApp->devicePixelRatio());
4585+ rewritten = rewriteSciFile(selectedFilePath, scaleFactorInDevicePixels, output);
4586+ }
4587 rewrittenSciFile->close();
4588
4589 s_rewrittenSciFiles.insert(m_source, QSharedPointer<QTemporaryFile>(rewrittenSciFile));
4590@@ -112,6 +129,9 @@
4591 m_image->setSource(m_source);
4592 }
4593 }
4594+ // explicitly set the source size in the QQuickImageBase, this persuades it that the
4595+ // supplied image is suitable for the current devicePixelRatio.
4596+ m_image->setSourceSize(m_image->sourceSize());
4597 }
4598 }
4599
4600
4601=== modified file 'src/Ubuntu/Components/plugin/ucstatesaver.cpp'
4602--- src/Ubuntu/Components/plugin/ucstatesaver.cpp 2015-07-22 14:35:48 +0000
4603+++ src/Ubuntu/Components/plugin/ucstatesaver.cpp 2015-09-08 04:09:38 +0000
4604@@ -147,7 +147,7 @@
4605 * \instantiates UCStateSaverAttached
4606 * \inqmlmodule Ubuntu.Components 1.1
4607 * \ingroup ubuntu-services
4608- * \brief Attached propertyes to save component property states.
4609+ * \brief Attached properties to save component property states.
4610 *
4611 * StateSaver attached object provides the ability to save component property values
4612 * that can be restored after an inproper application close. The properties subject
4613@@ -297,7 +297,7 @@
4614 * List of properties to be serialized, separated with commas. Properties must be
4615 * writable and can only be \l{http://qt-project.org/doc/qt-5.0/qtqml/qtqml-typesystem-basictypes.html}{QML base types}.
4616 *
4617- * A custom singl eline input which saves the text, polaceholderText, font and color would look as follows:
4618+ * A custom single line input which saves the text, placeholderText, font and color would look as follows:
4619 * \qml
4620 * TextField {
4621 * id: input
4622
4623=== modified file 'src/Ubuntu/Components/plugin/ucubuntushape.cpp'
4624--- src/Ubuntu/Components/plugin/ucubuntushape.cpp 2015-08-24 20:49:41 +0000
4625+++ src/Ubuntu/Components/plugin/ucubuntushape.cpp 2015-09-08 04:09:38 +0000
4626@@ -318,10 +318,7 @@
4627 setFlag(ItemHasContents);
4628 QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), this,
4629 SLOT(_q_gridUnitChanged()));
4630- const float gridUnit = UCUnits::instance().gridUnit();
4631- setImplicitWidth(implicitWidthGU * gridUnit);
4632- setImplicitHeight(implicitHeightGU * gridUnit);
4633- update();
4634+ _q_gridUnitChanged();
4635 }
4636
4637 /*! \qmlproperty string UbuntuShape::radius
4638@@ -803,9 +800,11 @@
4639 */
4640 void UCUbuntuShape::setColor(const QColor& color)
4641 {
4642- if (QuickUtils::showDeprecationWarnings()) {
4643- qmlInfo(this) << "'color' is deprecated. Use 'backgroundColor', 'secondaryBackgroundColor' and "
4644- "'backgroundMode' instead.";
4645+ static bool loggedOnce = false;
4646+ if (!loggedOnce) {
4647+ loggedOnce = true;
4648+ qmlInfo(this) << "'color' is deprecated. Use 'backgroundColor', 'secondaryBackgroundColor' "
4649+ "and 'backgroundMode' instead.";
4650 }
4651
4652 if (!(m_flags & BackgroundApiSet)) {
4653@@ -834,7 +833,9 @@
4654 */
4655 void UCUbuntuShape::setGradientColor(const QColor& gradientColor)
4656 {
4657- if (QuickUtils::showDeprecationWarnings()) {
4658+ static bool loggedOnce = false;
4659+ if (!loggedOnce) {
4660+ loggedOnce = true;
4661 qmlInfo(this) << "'gradientColor' is deprecated. Use 'backgroundColor', "
4662 "'secondaryBackgroundColor' and 'backgroundMode' instead.";
4663 }
4664@@ -863,7 +864,9 @@
4665 */
4666 void UCUbuntuShape::setImage(const QVariant& image)
4667 {
4668- if (QuickUtils::showDeprecationWarnings()) {
4669+ static bool loggedOnce = false;
4670+ if (!loggedOnce) {
4671+ loggedOnce = true;
4672 qmlInfo(this) << "'image' is deprecated. Use 'source' instead.";
4673 }
4674
4675@@ -894,7 +897,9 @@
4676 // maintain it for a while for compatibility reasons.
4677 void UCUbuntuShape::setStretched(bool stretched)
4678 {
4679- if (QuickUtils::showDeprecationWarnings()) {
4680+ static bool loggedOnce = false;
4681+ if (!loggedOnce) {
4682+ loggedOnce = true;
4683 qmlInfo(this) << "'stretched' is deprecated. Use 'sourceFillMode' instead";
4684 }
4685
4686@@ -915,8 +920,11 @@
4687 // Deprecation layer. Same comment as setStretched().
4688 void UCUbuntuShape::setHorizontalAlignment(HAlignment horizontalAlignment)
4689 {
4690- if (QuickUtils::showDeprecationWarnings()) {
4691- qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceHorizontalAlignment' instead";
4692+ static bool loggedOnce = false;
4693+ if (!loggedOnce) {
4694+ loggedOnce = true;
4695+ qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceHorizontalAlignment' "
4696+ "instead";
4697 }
4698
4699 if (!(m_flags & SourceApiSet)) {
4700@@ -932,8 +940,11 @@
4701 // Deprecation layer. Same comment as setStretched().
4702 void UCUbuntuShape::setVerticalAlignment(VAlignment verticalAlignment)
4703 {
4704- if (QuickUtils::showDeprecationWarnings()) {
4705- qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceVerticalAlignment' instead";
4706+ static bool loggedOnce = false;
4707+ if (!loggedOnce) {
4708+ loggedOnce = true;
4709+ qmlInfo(this) << "'horizontalAlignment' is deprecated. Use 'sourceVerticalAlignment' "
4710+ "instead";
4711 }
4712
4713 if (!(m_flags & SourceApiSet)) {
4714@@ -1009,20 +1020,11 @@
4715 updateFromImageProperties(qobject_cast<QQuickItem*>(sender()));
4716 }
4717
4718-void UCUbuntuShape::_q_openglContextDestroyed()
4719-{
4720- // Delete the shape textures that are stored per context and shared by all the shape items.
4721- const int index = getShapeTexturesIndex(qobject_cast<QOpenGLContext*>(sender()));
4722- Q_ASSERT(index >= 0);
4723- shapeTextures[index].openglContext = NULL;
4724- glDeleteTextures(shapeTextureCount, shapeTextures[index].textureId);
4725-}
4726-
4727 void UCUbuntuShape::_q_gridUnitChanged()
4728 {
4729- const float gridUnit = UCUnits::instance().gridUnit();
4730- setImplicitWidth(implicitWidthGU * gridUnit);
4731- setImplicitHeight(implicitHeightGU * gridUnit);
4732+ const float gridUnitInDevicePixels = UCUnits::instance().gridUnit() / qGuiApp->devicePixelRatio();
4733+ setImplicitWidth(implicitWidthGU * gridUnitInDevicePixels);
4734+ setImplicitHeight(implicitHeightGU * gridUnitInDevicePixels);
4735 update();
4736 }
4737
4738@@ -1170,8 +1172,10 @@
4739 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shapeTextureSize, shapeTextureSize, 0, GL_RGBA,
4740 GL_UNSIGNED_BYTE, shapeTextureData[i]);
4741 }
4742- QObject::connect(openglContext, SIGNAL(aboutToBeDestroyed()), this,
4743- SLOT(_q_openglContextDestroyed()), Qt::DirectConnection);
4744+ connect(openglContext, &QOpenGLContext::aboutToBeDestroyed, [index] {
4745+ shapeTextures[index].openglContext = NULL;
4746+ glDeleteTextures(shapeTextureCount, shapeTextures[index].textureId);
4747+ } );
4748 }
4749 const quint32 shapeTextureId = shapeTextures[index].textureId[m_aspect != DropShadow ? 0 : 1];
4750
4751@@ -1184,13 +1188,15 @@
4752 sourceTextureRect = sourceTexture->normalizedTextureSubRect();
4753 }
4754 if (m_flags & DirtySourceTransform) {
4755+ const float dpr = qGuiApp->devicePixelRatio();
4756+
4757 if (m_flags & SourceApiSet) {
4758- updateSourceTransform(itemSize.width(), itemSize.height(), m_sourceFillMode,
4759+ updateSourceTransform(itemSize.width() * dpr, itemSize.height() * dpr, m_sourceFillMode,
4760 m_sourceHorizontalAlignment, m_sourceVerticalAlignment,
4761 sourceTexture->textureSize());
4762 } else {
4763 FillMode imageFillMode = (m_flags & Stretched) ? Stretch : PreserveAspectCrop;
4764- updateSourceTransform(itemSize.width(), itemSize.height(), imageFillMode,
4765+ updateSourceTransform(itemSize.width() * dpr, itemSize.height() * dpr, imageFillMode,
4766 m_imageHorizontalAlignment, m_imageVerticalAlignment,
4767 sourceTexture->textureSize());
4768 }
4769@@ -1220,13 +1226,15 @@
4770 // accordingly. The shape was using a fixed image for the corner before switching to a
4771 // distance field, since the corner wasn't taking the whole image (ending at ~80%) we need
4772 // to take that into account when the size is scaled down.
4773- radius = UCUnits::instance().gridUnit() * radiusGuMap[m_radius];
4774+ radius = UCUnits::instance().gridUnit() * radiusGuMap[m_radius]
4775+ / qGuiApp->devicePixelRatio();
4776 const float scaledDownRadius = qMin(itemSize.width(), itemSize.height()) * 0.5f * 0.8f;
4777 if (radius > scaledDownRadius) {
4778 radius = scaledDownRadius;
4779 }
4780 } else {
4781- radius = qMin(itemSize.width(), itemSize.height()) * 0.5f * (m_relativeRadius * 0.01f);
4782+ radius = qMin(itemSize.width(), itemSize.height()) * 0.5f * (m_relativeRadius * 0.01f)
4783+ / qGuiApp->devicePixelRatio();
4784 }
4785
4786 updateMaterial(node, radius, shapeTextureId, sourceTexture && m_sourceOpacity);
4787@@ -1306,16 +1314,19 @@
4788 materialData->sourceOpacity = 0;
4789 }
4790
4791+ const float physicalRadius = radius * qGuiApp->devicePixelRatio();
4792+
4793 // Mapping of radius size range from [0, 4] to [0, 1] with clamping, plus quantization.
4794 const float start = 0.0f + radiusSizeOffset;
4795 const float end = 4.0f + radiusSizeOffset;
4796+
4797 materialData->distanceAAFactor =
4798- qMin((radius / (end - start)) - (start / (end - start)), 1.0f) * 255.0f;
4799+ qMin((physicalRadius / (end - start)) - (start / (end - start)), 1.0f) * 255.0f;
4800
4801 // When the radius is equal to radiusSizeOffset (which means radius size is 0), no aspect is
4802 // flagged so that a dedicated (statically flow controlled) shaved off shader can be used for
4803 // optimal performance.
4804- if (radius > radiusSizeOffset) {
4805+ if (physicalRadius > radiusSizeOffset) {
4806 const quint8 aspectFlags[] = {
4807 ShapeMaterial::Data::Flat, ShapeMaterial::Data::Inset, ShapeMaterial::Data::DropShadow,
4808 ShapeMaterial::Data::Inset | ShapeMaterial::Data::Pressed
4809
4810=== modified file 'src/Ubuntu/Components/plugin/ucubuntushape.h'
4811--- src/Ubuntu/Components/plugin/ucubuntushape.h 2015-08-06 13:16:24 +0000
4812+++ src/Ubuntu/Components/plugin/ucubuntushape.h 2015-09-08 04:09:38 +0000
4813@@ -296,7 +296,6 @@
4814
4815 private Q_SLOTS:
4816 void _q_imagePropertiesChanged();
4817- void _q_openglContextDestroyed();
4818 void _q_gridUnitChanged();
4819 void _q_providerDestroyed(QObject* object=0);
4820 void _q_textureChanged();
4821
4822=== modified file 'src/Ubuntu/Components/plugin/ucunits.cpp'
4823--- src/Ubuntu/Components/plugin/ucunits.cpp 2015-03-03 13:47:48 +0000
4824+++ src/Ubuntu/Components/plugin/ucunits.cpp 2015-09-08 04:09:38 +0000
4825@@ -24,6 +24,8 @@
4826 #include <QtCore/QDir>
4827 #include <QtCore/QRegularExpression>
4828 #include <QtCore/qmath.h>
4829+#include <QtGui/QGuiApplication>
4830+#include <QtGui/QScreen>
4831
4832 #define ENV_GRID_UNIT_PX "GRID_UNIT_PX"
4833 #define DEFAULT_GRID_UNIT_PX 8
4834@@ -62,10 +64,46 @@
4835
4836 \sa {Resolution Independence}
4837 */
4838+
4839+/*
4840+ * Note on the interaction between GRID_UNIT_PX and QT_DEVICE_PIXEL_RATIO
4841+ *
4842+ * In Qt5.4 there is a single means to scale the UI: the QT_DEVICE_PIXEL_RATIO environment
4843+ * variable. This accepts only integer values, thus allowing a x2 or x3 scaling of any
4844+ * Qt-based UI, that includes QWidget as well as any QML UI.
4845+ *
4846+ * Setting QT_DEVICE_PIXEL_RATIO=2 implies one density-independent pixel corresponds to 2
4847+ * physical pixels. Developers describe their UI in terms of density-independent pixels.
4848+ * Qt scales accordingly.
4849+ *
4850+ * The Ubuntu UI Toolkit has solved the scaling problem with the GRID_UNIT_PX variable.
4851+ * It offers more flexibility, but only scales QML applications written to use the UITK
4852+ * (since it uses this Units class) as it is built on top of QML.
4853+ *
4854+ * There are additional areas in Qt where QT_DEVICE_PIXEL_RATIO causes correct scaling which
4855+ * GRID_UNIT_PX cannot, for example:
4856+ * 1. cacheBuffer for ListView/GridViews - specified in density-independent pixels
4857+ * 2. gesture recognition matches what is on screen better, as it is density-independent
4858+ * pixel aware
4859+ *
4860+ * In order to get the best of both worlds, Ubuntu will set both GRID_UNIT_PX and
4861+ * QT_DEVICE_PIXEL_RATIO. Thus all Qt apps will scale reasonably well, with UITK-based apps
4862+ * scaling perfectly for any desired scale (i.e. non-integer scales).
4863+ *
4864+ * However UITK developers can just use this Units class as usual, and will be almost totally
4865+ * isolated from Qt's own scaling concept.
4866+ */
4867+
4868 UCUnits::UCUnits(QObject *parent) :
4869- QObject(parent)
4870+ QObject(parent),
4871+ m_devicePixelRatio(qGuiApp->devicePixelRatio())
4872 {
4873- m_gridUnit = getenvFloat(ENV_GRID_UNIT_PX, DEFAULT_GRID_UNIT_PX);
4874+ // If GRID_UNIT_PX set, always use it. If not, 1GU := DEFAULT_GRID_UNIT_PX * m_devicePixelRatio
4875+ if (qEnvironmentVariableIsSet(ENV_GRID_UNIT_PX)) {
4876+ m_gridUnit = getenvFloat(ENV_GRID_UNIT_PX, DEFAULT_GRID_UNIT_PX);
4877+ } else {
4878+ m_gridUnit = DEFAULT_GRID_UNIT_PX * m_devicePixelRatio;
4879+ }
4880 }
4881
4882 /*!
4883@@ -89,14 +127,15 @@
4884
4885 Returns the number of pixels \a value density independent pixels correspond to.
4886 */
4887+// Density-independent pixels (and not physical pixels) because Qt sizes in terms of density-independent pixels.
4888 float UCUnits::dp(float value)
4889 {
4890 const float ratio = m_gridUnit / DEFAULT_GRID_UNIT_PX;
4891 if (value <= 2.0) {
4892 // for values under 2dp, return only multiples of the value
4893- return qRound(value * qFloor(ratio));
4894+ return qRound(value * qFloor(ratio)) / m_devicePixelRatio;
4895 } else {
4896- return qRound(value * ratio);
4897+ return qRound(value * ratio) / m_devicePixelRatio;
4898 }
4899 }
4900
4901@@ -105,9 +144,11 @@
4902
4903 Returns the number of pixels \a value grid units correspond to.
4904 */
4905+// Density-independent pixels (and not physical pixels) because Qt sizes in terms of density-independent pixels.
4906+
4907 float UCUnits::gu(float value)
4908 {
4909- return qRound(value * m_gridUnit);
4910+ return qRound(value * m_gridUnit) / m_devicePixelRatio;
4911 }
4912
4913 QString UCUnits::resolveResource(const QUrl& url)
4914
4915=== modified file 'src/Ubuntu/Components/plugin/ucunits.h'
4916--- src/Ubuntu/Components/plugin/ucunits.h 2013-10-18 08:56:39 +0000
4917+++ src/Ubuntu/Components/plugin/ucunits.h 2015-09-08 04:09:38 +0000
4918@@ -53,6 +53,7 @@
4919 float gridUnitSuffixFromFileName(const QString &fileName);
4920
4921 private:
4922+ float m_devicePixelRatio;
4923 float m_gridUnit;
4924 };
4925
4926
4927=== modified file 'src/Ubuntu/Components/plugin/ucviewitemsattached.cpp'
4928--- src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-03-17 16:48:59 +0000
4929+++ src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-09-08 04:09:38 +0000
4930@@ -104,6 +104,7 @@
4931 : QObjectPrivate()
4932 , listView(0)
4933 , dragArea(0)
4934+ , expansionFlags(UCViewItemsAttached::Exclusive)
4935 , globalDisabled(false)
4936 , selectable(false)
4937 , draggable(false)
4938@@ -556,7 +557,7 @@
4939 return;
4940 }
4941 dragArea = new ListItemDragArea(listView);
4942- dragArea->init();
4943+ dragArea->init(q_func());
4944 }
4945
4946 void UCViewItemsAttachedPrivate::leaveDragMode()
4947@@ -611,3 +612,142 @@
4948 Q_EMIT q->selectedIndicesChanged();
4949 }
4950 }
4951+
4952+
4953+UCViewItemsAttached13::UCViewItemsAttached13(QObject *owner)
4954+ : UCViewItemsAttached(owner)
4955+{
4956+ d_ptr = UCViewItemsAttachedPrivate::get(this);
4957+}
4958+
4959+UCViewItemsAttached13 *UCViewItemsAttached13::qmlAttachedProperties(QObject *owner)
4960+{
4961+ return new UCViewItemsAttached13(owner);
4962+}
4963+
4964+/*!
4965+ * \qmlattachedproperty list<int> ViewItems::expandedIndices
4966+ * \since Ubuntu.Components 1.3
4967+ * The property contains the indexes of the ListItems marked as expanded. The
4968+ * indexes are model indexes when used in ListView, and child indexes in other
4969+ * components. The property being writable, initial expansion configuration
4970+ * can be provided for a view, and provides ability to save the expansion state.
4971+ * \note If the \l ViewItems::expansionFlags is having \c ViewItems.Exclusive
4972+ * flags set, only the last item from the list will be considered and set as
4973+ * expanded.
4974+ */
4975+QList<int> UCViewItemsAttached13::expandedIndices() const
4976+{
4977+ Q_D(const UCViewItemsAttached);
4978+ return d->expansionList.keys();
4979+}
4980+void UCViewItemsAttached13::setExpandedIndices(QList<int> indices)
4981+{
4982+ Q_UNUSED(indices);
4983+ Q_D(UCViewItemsAttached);
4984+ d->collapseAll();
4985+ if (indices.size() > 0) {
4986+ if (d->expansionFlags & UCViewItemsAttached::Exclusive) {
4987+ // take only the last one from the list
4988+ d->expand(indices.last(), QPointer<UCListItem13>(), false);
4989+ } else {
4990+ for (int i = 0; i < indices.size(); i++) {
4991+ d->expand(indices[i], QPointer<UCListItem13>(), false);
4992+ }
4993+ }
4994+ }
4995+ Q_EMIT expandedIndicesChanged(d->expansionList.keys());
4996+}
4997+
4998+// insert listItem into the expanded indices map
4999+void UCViewItemsAttachedPrivate::expand(int index, UCListItem13 *listItem, bool emitChangeSignal)
5000+{
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: