This file is indexed.

/usr/lib/x86_64-linux-gnu/qt5/qml/Ubuntu/Components/1.3/ScrollView.qml is in qml-module-ubuntu-components-gles 1.3.1918+16.04.20160404-0ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/*
 * Copyright 2015 Canonical Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import QtQuick 2.4
import Ubuntu.Components 1.3

/*!
    \qmltype ScrollView
    \inqmlmodule Ubuntu.Components 1.3
    \ingroup ubuntu
    \inherits StyledItem
    \brief ScrollView is a scrollable view that features scrollbars and scrolling via keyboard keys.

    ScrollView is the recommended component to use in the implementation of scrollable content. It
    features scrollbars and handles keyboard input.
    Old applications that implemented scrollable views directly using the \l Scrollbar component should
    migrate to ScrollView, to ensure the UX is ready for convergent devices and is consistent with the
    rest of the platform.

    ScrollView wraps \l {Scrollbar}(s) in a view, and provides additional features such as:
    \list
    \li - Keyboard navigation and focus handling, for a complete convergent experience.
    \li - Automatic position handling of vertical and horizontal scrollbars, preventing them from
          overlapping one another when both on screen.
    \endlist

    Adding scrollbars and keyboard input handling to a QML item is as simple as wrapping that item in a
    ScrollView, as shown in the following example:

    \qml
    import QtQuick 2.4
    import Ubuntu.Components 1.3

    ScrollView {
        width: units.gu(40)
        height: units.gu(30)

        Rectangle {
            width: units.gu(140)
            height: units.gu(40)
            gradient: Gradient {
                GradientStop { position: 0.0; color: "lightsteelblue" }
                GradientStop { position: 1.0; color: "blue" }
            }
        }
    }
    \endqml

    NOTE: the items that are wrapped in the ScrollView are reparanted to \l viewport.
*/
StyledItem {
    id: root

    implicitWidth: 240
    implicitHeight: 150
    activeFocusOnPress: true

    //TODO: add horizontalScrollbarPolicy
    //TODO: add verticalScrollbarPolicy

    //Currently we want to push the platform towards overlay scrollbars
    //readonly property bool alwaysOnScrollbars: false

    /*!
        \qmlproperty Item ScrollView::viewport
        This property holds the viewport Item. The children of the ScrollView element are
        reparented to this item to make sure the scrollbars are correctly positioned and
        the items are clipped at their boundaries.
    */
    readonly property alias viewport: viewportItem

    /*!
        \qmlproperty Item ScrollView::flickableItem
        The flickableItem of the ScrollView. If the contentItem provided
        to the ScrollView is a Flickable, that will be the \l flickableItem.
        Otherwise ScrollView will create a Flickable which will hold the
        items provided as children.
    */
    readonly property alias flickableItem: internal.flickableItem

    /*!
        The contentItem of the ScrollView. This is set by the user.
        Note that the definition of contentItem is somewhat different to that
        of a Flickable, where the contentItem is implicitly created.
    */
    default property Item contentItem

    Keys.enabled: true
    Keys.onLeftPressed: {
        if (horizontalScrollbar.__styleInstance !== null) {
            horizontalScrollbar.__styleInstance.scrollBy(-flickableItem.width*internal.shortScrollingRatio, true)
        }
    }
    Keys.onRightPressed: {
        if (horizontalScrollbar.__styleInstance !== null) {
            horizontalScrollbar.__styleInstance.scrollBy(flickableItem.width*internal.shortScrollingRatio, true)
        }
    }
    Keys.onDownPressed: {
        if (verticalScrollbar.__styleInstance !== null) {
            verticalScrollbar.__styleInstance.scrollBy(flickableItem.height*internal.shortScrollingRatio, true)
        }
    }
    Keys.onUpPressed: {
        if (verticalScrollbar.__styleInstance !== null) {
            verticalScrollbar.__styleInstance.scrollBy(-flickableItem.height*internal.shortScrollingRatio, true)
        }
    }
    Keys.onPressed:  {
        if (event.key == Qt.Key_Escape) {
            var scrollbarWithActiveDrag = (horizontalScrollbar.__styleInstance && horizontalScrollbar.__styleInstance.draggingThumb && horizontalScrollbar)
                    || (verticalScrollbar.__styleInstance && verticalScrollbar.__styleInstance.draggingThumb && verticalScrollbar)
                    || null
            if (scrollbarWithActiveDrag !== null) {
                scrollbarWithActiveDrag.__styleInstance.resetScrollingToPreDrag()
                event.accepted = true
            }
        } else if (verticalScrollbar.__styleInstance !== null) {
            if (event.key == Qt.Key_PageDown) {
                verticalScrollbar.__styleInstance.scrollBy(flickableItem.height*internal.longScrollingRatio, true)
                event.accepted = true
            } else if (event.key == Qt.Key_PageUp) {
                verticalScrollbar.__styleInstance.scrollBy(-flickableItem.height*internal.longScrollingRatio, true)
                event.accepted = true
            } else if (event.key == Qt.Key_Home) {
                verticalScrollbar.__styleInstance.scrollToBeginning(true)
                event.accepted = true
            } else if (event.key == Qt.Key_End) {
                verticalScrollbar.__styleInstance.scrollToEnd(true)
                event.accepted = true
            }
        }
    }

    onContentItemChanged: {
        // Check if the item provided is a Flickable
        if (QuickUtils.inherits(contentItem, "QQuickFlickable")) {
            internal.flickableItem = contentItem
            internal.flickableItem.parent = viewportItem
        } else {
            //Create a dummy Flickable if the app dev didn't provide any
            internal.flickableItem = flickableComponent.createObject(viewportItem)
            contentItem.parent = internal.flickableItem.contentItem
        }
        internal.flickableItem.anchors.fill = viewportItem
    }

    /*!
        \qmlproperty Scrollbar ScrollView::horizontalScrollbar

        This property holds the horizontal scrollbar used in the ScrollView.
        It provides access to the scrollbar thus making it possible to change its properties or
        completely replace it with a custom \l Scrollbar object.

        This property defaults to an instance of \l Scrollbar.

        \b NOTE: some \l Scrollbar properties are already handled by ScrollView, and their value
        should hence not be overridden. These properties are:
        \list
        \li anchors margins, such as anchors.topMargin etc.
        \li the parent Item
        \li \l Scrollbar::flickableItem
        \endlist
    */
    property Scrollbar horizontalScrollbar: Scrollbar {
        objectName: "horizontalScrollbar"
        align: Qt.AlignBottom
        focus: false
    }

    /*!
        \qmlproperty Scrollbar ScrollView::verticalScrollbar

        This property holds the vertical scrollbar used in the ScrollView.
        It provides access to the scrollbar thus making it possible to change its properties or
        completely replace it with a custom \l Scrollbar object.

        This property defaults to an instance of \l Scrollbar.

        \b NOTE: some \l Scrollbar properties are already handled by ScrollView, and their value
        should hence not be overridden. These properties are:
        \list
        \li anchors margins, such as anchors.topMargin etc.
        \li the parent Item
        \li \l Scrollbar::flickableItem
        \endlist
    */
    property Scrollbar verticalScrollbar: Scrollbar {
        objectName: "verticalScrollbar"
        align: Qt.AlignTrailing
        focus: false
    }

    children: [
        Item {
            id: viewportItem
            anchors.fill: parent
            anchors.topMargin: (horizontalScrollbar.align === Qt.AlignTop && horizontalScrollbar.__alwaysOnScrollbars)
                               ? internal.nonOverlayScrollbarMargin : 0
            anchors.leftMargin: (verticalScrollbar.align === Qt.AlignLeading && horizontalScrollbar.__alwaysOnScrollbars)
                                ? internal.nonOverlayScrollbarMargin : 0
            anchors.rightMargin: (verticalScrollbar.align === Qt.AlignTrailing && horizontalScrollbar.__alwaysOnScrollbars)
                                 ? internal.nonOverlayScrollbarMargin : 0
            anchors.bottomMargin: (horizontalScrollbar.align === Qt.AlignBottom && horizontalScrollbar.__alwaysOnScrollbars)
                                  ? internal.nonOverlayScrollbarMargin : 0

            clip: true
            focus: true
        },

        Item {
            id: internal
            anchors.fill: parent

            property Flickable flickableItem
            property real nonOverlayScrollbarMargin: verticalScrollbar.__styleInstance ? verticalScrollbar.__styleInstance.nonOverlayScrollbarMargin : 0
            //shortScrollingRation is used for arrow keys, longScrollingRatio is used for pgUp/pgDown
            //0.1 means we will scroll 10% of the *visible* flickable area
            property real shortScrollingRatio: __styleInstance ? __styleInstance.shortScrollingRatio : 0.1
            property real longScrollingRatio: __styleInstance ? __styleInstance.longScrollingRatio : 0.9

            Component {
                id: flickableComponent
                Flickable {}
            }

            //if the flickable is not coming from the user but from our internal Component...
            Binding {
                target: flickableItem
                when: contentItem !== flickableItem
                property: "contentHeight"
                value: contentItem ? contentItem.height : 0
            }
            Binding {
                target: flickableItem
                when: contentItem !== flickableItem
                property: "contentWidth"
                value: contentItem ? contentItem.width : 0
            }

            Binding {
                when: root.verticalScrollbar
                target: root.verticalScrollbar
                property: "parent"
                value: root
            }
            Binding {
                when: root.horizontalScrollbar
                target: root.horizontalScrollbar
                property: "parent"
                value: root
            }

            //The viewport MUST be set, when Scrollbar is used inside a ScrollView, because that is the
            //item it will anchor to.
            Binding {
                //NOTE: we have to wait for the parent to be set before setting the viewport item or that
                //will trigger anchoring errors
                when: root.horizontalScrollbar && root.horizontalScrollbar.parent
                target: root.horizontalScrollbar
                property: "__viewport"
                value: viewportItem
            }
            Binding {
                when: root.verticalScrollbar && root.verticalScrollbar.parent
                target: root.verticalScrollbar
                property: "__viewport"
                value: viewportItem
            }

            Binding {
                //wait for viewport to be set, otherwise Scrollbar will try anchoring to flickableItem, which
                //is not a parent or sibling (see definition of Scrollbar anchors) when Scrollbar is inside
                //a ScrollView (it is a sibling usually when Scrollbar is used directly, without ScrollView)
                when: root.horizontalScrollbar && root.horizontalScrollbar.__viewport
                target: root.horizontalScrollbar
                property: "flickableItem"
                value: internal.flickableItem
            }
            Binding {
                when: root.verticalScrollbar && root.verticalScrollbar.__viewport
                target: root.verticalScrollbar
                property: "flickableItem"
                value: internal.flickableItem
            }

            Binding {
                when: root.verticalScrollbar
                target: root.verticalScrollbar
                property: "__buddyScrollbar"
                value: root.horizontalScrollbar
            }
            Binding {
                when: root.horizontalScrollbar
                target: root.horizontalScrollbar
                property: "__buddyScrollbar"
                value: root.verticalScrollbar
            }

            //When you click outside of a child of the scrollview, this restores the focus to the ScrollView
            //Why is this needed?
            //  Suppose the viewport has a child ScrollView (or another Item which handles some or all of the hw keys we handle).
            //  Now, if that child is coded to set its focus to true when you tap on it (which is, for instance, what
            //  StyledItem's activeFocusOnPress does), tapping on that child will set viewportItem.focus = false, because
            //  that child is just another Item inside "root" and "root" is a FocusScope, and that's how FocusScope works.
            //  At this point, we need something to restore the focus to the viewportItem once you tap on viewportItem, outside
            //  any other child. And that's what the MouseArea below does.
            //
            //The alternative could be making the viewport a StyledItem and using activeFocusOnPress:true, but that wouldn't work
            //because it would make viewportItem a focus scope, and we don't want that, because at that point,
            //being in a similar situation as described above, we wouldn't be able to transfer the focus to viewportItem, because
            //being a focus scope means viewportItem would forward the focus to the one between its children who asked it most
            //recently
            MouseArea {
                anchors.fill: parent
                onPressed: {
                    //FIXME: we can't force focus on the viewport, this breaks text selection inside scrollview!
                    //+ it still doesn't work in Sliders page, for yet unknown reasons
                    //Without this we can't shift focus from a child ScrollView to a parent ScrollView
                    //viewportItem.focus = true

                    //activeFocusOnPress only works if *all* the parents have activeFocusOnPress enabled
                    //Some applications (like messaging-app at the moment) have activeFocusOnPress:false on
                    //the MainView, and that would make focusing the scrollview impossible. Hence we also
                    //force it from QML side
                    root.forceActiveFocus()

                    mouse.accepted = false
                }
            }
        }
    ]
}