This file is indexed.

/usr/lib/x86_64-linux-gnu/qt5/qml/Ubuntu/Components/Pickers/1.2/DatePicker.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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
/*
 * Copyright 2013 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.2

/*!
    \qmltype DatePicker
    \inqmlmodule Ubuntu.Components.Pickers 1.0
    \ingroup ubuntu-pickers
    \brief DatePicker component provides date and time value picking functionality.

    DatePicker combines up to three Picker elements providing different date or time
    value selection possibilities. It can be used to select full date (year, month,
    day), full time (hours, minutes, seconds) as well as to select a combination of
    year and month, month and day, hours and minutes, minutes and seconds or individual
    time units (i.e. year, month or day as well as hours, minutes or seconds). The
    selected date as well as the initial one is provided by the \l date property.
    For convenience the component provides also the \a year, \a month, \a day,
    \a week, \a hours, \a minutes and \a seconds values as separate properties,
    however these properties are not writable, and their initialization can happen
    only through the \l date property.

    \qml
    import QtQuick 2.4
    import Ubuntu.Components 1.2
    import Ubuntu.Components.Pickers 1.0

    Column {
        Label {
            text: "Selected date: W" + datePicker.week + " - " +
                    Qt.formatDate(datePicker.date, "dddd, dd-MMMM-yyyy")
        }
        DatePicker {
            id: datePicker
        }
    }
    \endqml

    The \l mode property specifies what time units should be shown by the picker.
    The property holds a string, combining \b Years, \b Months, \b Days, \b Hours,
    \b Minutes and \b Seconds strings sepatared with '|' character. A DatePicker
    which shows only year and month date units would look as follows:
    \qml
    import QtQuick 2.4
    import Ubuntu.Components 1.2
    import Ubuntu.Components.Pickers 1.0

    Column {
        Label {
            text: "Selected month: " + Qt.formatDate(datePicker.date, "MMMM-yyyy")
        }
        DatePicker {
            id: datePicker
            mode: "Years|Months"
        }
    }
    \endqml

    The \b mode of the DatePicker is set to date picking. In case time picking
    is needed, the model should be set to contain the time specific mode flags.
    The following example demonstrates how to use DatePicker for time picking.
    \qml
    import QtQuick 2.4
    import Ubuntu.Components 1.2
    import Ubuntu.Components.Pickers 1.0

    Column {
        Label {
            text: "Selected time: " + Qt.formatTime(datePicker.date, "hh:mm:ss")
        }
        DatePicker {
            id: datePicker
            mode: "Hours|Minutes|Seconds"
        }
    }
    \endqml
    Note that the order in which the mode flags are specified does not influence
    the order the pickers are arranged. That is driven by the date format of the
    \l locale used in the picker. Also not all combinations of mode flags are
    supported. See \l mode for the supported combinations.

    The default interval the date values are chosen is a window starting at
    the current date ending 50 years later. This window is defined by the
    \a minimum and \a maximum properties. The interval can be altered considering
    the following rules:
    \list
        \li \a minimum must be less or equal than the \l date; if the \a date
                value is less than the given \a minimum, the date will be set to
                the minimum's value
        \li \a maximum value must be greater than the \a minimum, or invalid.
                When the maximum is smaller than the \l date, the \l date property
                will be updated to get the maximum value.
                When set to invalid date (see Date.getInvalidDate()), the upper
                limit of the date interval becomes infinite, meaning the year
                picker will extend infinitely. This leads to increased memory
                use and should be avoided if possible. Invalid date will make
                hours picker presenting 24 hours.
    \endlist
    \qml
    import QtQuick 2.4
    import Ubuntu.Components 1.2
    import Ubuntu.Components.Pickers 1.0

    Column {
        Label {
            text: "Selected date: " + Qt.formatDate(datePicker.date, "dddd, dd-MMMM-yyyy")
        }
        DatePicker {
            id: datePicker
            minimum: {
                var d = new Date();
                d.setFullYear(d.getFullYear() - 1);
                return d;
            }
            maximum: Date.prototype.getInvalidDate.call()
        }
    }
    \endqml
    \b Note: do not use the \l date property when initializing minimum and maximum
    as it will cause binding loops.

    \section2 Layout
    As mentioned earlier, DatePicker combines up to three Picker tumblers depending
    on the mode requested. These tumblers are laid out in a row in the order the
    default date format of the \l locale is.

    \section3 Date picker layout rules
    The date picker consist of three pickers: year, month, and date. The exact
    contents of the month and date pickers depends on the available width:
    \list
        \li full name for month, number and full day for date (“August” “28 Wednesday”)
        \li otherwise full name for month, number and abbreviated day
            for date (“August” “28 Wed”);
        \li otherwise full name for month, number for date (“August” “28”);
        \li otherwise abbreviated name for month, number for date (“Aug” “28”).
        \li otherwise number for month, number for date (“08” “28”).
    \endlist

    \a{If the currently selected date becomes impossible due to year change (from a
    leap to a non-leap year when the date is set to February 29) or month change
    (e.g. from a month that has 31 days to one that has fewer when the date is
    set to 31), the date reduces automatically to the last day of the month (i.e
    February 28 or 30th day of the month).}

    \section3 Time picker layout rules
    Time units are shown in fixed width picker tumblers, numbers padded with
    leading zeroes. There is no other special rule on the formatting of the time
    unit numbers.

    \section3 How minimum/maximum affects the tumblers

    If minimum and maximum are within the same year, the year picker will be
    insensitive. If minimum and maximum are within the same month, the month picker
    will also be insensitive.
  */
StyledItem {
    id: datePicker

    /*!
      Specifies what kind of date value selectors should be shown by the picker.
      This is a string of 'flags' separated by '|' separator, where flags are:
      \table
        \header
        \li {2, 1} Date picker modes
            \header
                \li Value
                \li Description
            \row
                \li Years
                \li Specifies to show the year picker
            \row
                \li Months
                \li Specifies to show the month picker
            \row
                \li Days
                \li Specifies to show the day picker
        \header
        \li {2, 1} Time picker modes
            \header
                \li Value
                \li Description
            \row
                \li Hours
                \li Specifies to show the hours picker
            \row
                \li Minutes
                \li Specifies to show the minutes picker
            \row
                \li Seconds
                \li Specifies to show the seconds picker
      \endtable
      With some exceptions, any combination of these flags is allowed within the
      same group. Date and time picker modes cannot be combined.

      The supported combinations are: \a{Years|Months|Days}, \a{Years|Months},
      \a{Months|Days}, \a{Hours|Minutes|Seconds}, \a{Hours|Minutes} and \a{Minutes|Seconds},
      as well as each mode flag individually.

      The default value is "\a{Years|Months|Days}".
      */
    property string mode: "Years|Months|Days"

    /*!
      The date chosen by the DatePicker. The default value is the date at the
      component creation time. The property automatically updates year, month
      and day properties.
      */
    property date date: Date.prototype.midnight.call(new Date())

    /*!
      \qmlproperty int minimum
      The minimum date (inclusive) to be shown in the picker.
      Both year and month values will be considered from the properties.

      The year and month picker values are filled based on these values. The
      year picker will be infinite (extending infinitely) if the maximum is
      an invalid date. If the distance between maximum and minimum is less than
      a year, the year picker will be shown disabled.

      The month picker will be circular if the distance between maximum and minimum
      is at least one year, or if the maximum date is invalid.

      The default values are the current date for the minimum, and 50 year distance
      value for maximum.
      */
    property date minimum: Date.prototype.midnight.call(new Date())
    /*!
      \qmlproperty int maximum

      The maximum date (inclusive) to be shown in the picker.
      Both year and month values will be considered from the properties.

      See \l minimum for more details.
     */
    property date maximum: {
        var d = Date.prototype.midnight.call(new Date());
        d.setFullYear(d.getFullYear() + 50);
        return d;
    }

    /*!
      For convenience, the \b year value of the \l date property.
      */
    readonly property int year: datePicker.date.getFullYear()
    /*!
      For convenience, the \b month value of the \l date property.
     */
    readonly property int month: datePicker.date.getMonth()
    /*!
      For convenience, the \b day value of the \l date property.
     */
    readonly property int day: datePicker.date.getDate()
    /*!
      For convenience, the \b week value of the \l date property.
     */
    readonly property int week: datePicker.date.getWeek()
    /*!
      For convenience, the \b hours value of the \l date property.
     */
    readonly property int hours: datePicker.date.getHours()
    /*!
      For convenience, the \b minutes value of the \l date property.
     */
    readonly property int minutes: datePicker.date.getMinutes()
    /*!
      For convenience, the \b seconds value of the \l date property.
     */
    readonly property int seconds: datePicker.date.getSeconds()

    /*!
      The property defines the locale used in the picker. The default value is
      the system locale.
      \qml
      DatePicker {
           locale: Qt.locale("hu_HU")
      }
      \endqml
      */
    property var locale: Qt.locale()

    /*!
      \qmlproperty bool moving
      \readonly
      The property holds whether the component's pickers are moving.
      \sa Picker::moving
      */
    readonly property alias moving: positioner.moving

    implicitWidth: units.gu(36)
    implicitHeight: units.gu(20)
    activeFocusOnPress: true

    /*! \internal */
    onMinimumChanged: {
        if (internals.completed && !minimum.isValid()) {
            // set the minimum to the date
            minimum = date;
        }

        // adjust date
        if (date !== undefined && Date.prototype.isValid.call(minimum) && date < minimum && internals.completed) {
            date = minimum;
        }
    }
    /*! \internal */
    onMaximumChanged: {
        // adjust date
        if (date !== undefined && Date.prototype.isValid.call(maximum) && date > maximum && maximum > minimum  && internals.completed) {
            date = maximum;
        }
    }
    /*! \internal */
    onWidthChanged: {
        // use dayPicker narrowFormatLimit even if the dayPicker is hidden
        // and clamp the width so it cannot have less width that the sum of
        // the three tumblers' narrowFormatLimit
        var minWidth = 0.0;
        for (var i = 0; i < tumblerModel.count; i++) {
            minWidth += tumblerModel.get(i).pickerModel.narrowFormatLimit;
        }
        width = Math.max(width, minWidth);
    }
    /*! \internal */
    onModeChanged: internals.updatePickers()
    /*! \internal */
    onLocaleChanged: internals.updatePickers()

    Component.onCompleted: {
        if (minimum === undefined) {
            minimum = date;
        }
        internals.completed = true;
        internals.updatePickers();
    }

    // models
    YearModel {
        id: yearModel
        mainComponent: datePicker
        pickerCompleted: internals.completed && internals.showYearPicker
        pickerWidth: (!pickerItem) ? 0 : narrowFormatLimit
        function syncModels() {
            dayModel.syncModels();
        }
    }
    MonthModel {
        id: monthModel
        mainComponent: datePicker
        pickerCompleted: internals.completed && internals.showMonthPicker
        pickerWidth: {
            if (!pickerItem) {
                return 0;
            }
            return MathUtils.clamp(datePicker.width - yearModel.pickerWidth - dayModel.pickerWidth, narrowFormatLimit, longFormatLimit);
        }
        function syncModels() {
            dayModel.syncModels();
        }
    }
    DayModel {
        id: dayModel
        mainComponent: datePicker
        pickerCompleted: internals.completed && internals.showDayPicker
        pickerWidth: {
            if (!pickerItem) {
                return 0;
            }
            var w = Math.max(datePicker.width * internals.dayPickerRatio, narrowFormatLimit);
            if (w < longFormatLimit && w >= shortFormatLimit) {
                return shortFormatLimit;
            }
            return w;
        }
    }
    HoursModel {
        id: hoursModel
        mainComponent: datePicker
        pickerCompleted: internals.completed && internals.showHoursPicker
        pickerWidth: {
            if (!pickerItem) {
                return 0;
            }
            return narrowFormatLimit;
        }
    }
    MinutesModel {
        id: minutesModel
        mainComponent: datePicker
        pickerCompleted: internals.completed && internals.showMinutesPicker
        pickerWidth: {
            if (!pickerItem) {
                return 0;
            }
            return narrowFormatLimit;
        }
    }
    SecondsModel {
        id: secondsModel
        mainComponent: datePicker
        pickerCompleted: internals.completed && internals.showSecondsPicker
        pickerWidth: {
            if (!pickerItem) {
                return 0;
            }
            return narrowFormatLimit;
        }
    }

    style: Theme.createStyleComponent("DatePickerStyle.qml", datePicker)
    Binding {
        target: __styleInstance
        property: "view"
        value: positioner
    }
    Binding {
        target: __styleInstance
        property: "pickerModels"
        value: tumblerModel
    }
    Binding {
        target: __styleInstance
        property: "unitSeparator"
        value: (internals.showHoursPicker || internals.showMinutesPicker || internals.showSecondsPicker) ?
                   ":" : ""
    }

    // tumbler positioner
    PickerRow {
        id: positioner
        parent: (datePicker.__styleInstance && datePicker.__styleInstance.hasOwnProperty("tumblerHolder")) ?
                    datePicker.__styleInstance.tumblerHolder : datePicker
        mainComponent: datePicker
        model: tumblerModel
        margins: internals.margin
        anchors {
            top: parent.top
            bottom: parent.bottom
            horizontalCenter: parent.horizontalCenter
        }
    }
    // tumbler model
    ListModel {
        /*
              Model to hold tumbler order for repeaters.
              Roles:
              - pickerModel
              - pickerName
              */
        id: tumblerModel

        /*
          Signal triggered when the model is about to remove a picker. We cannot rely on
          rowAboutToBeRemoved, as by the time the signal is called the list element is
          already removed from the model.
          */
        signal pickerRemoved(int index)

        // the function checks whether a pickerModel was added or not
        // returns the index of the model object the pickerModel was found
        // or -1 on error.
        function pickerModelIndex(name) {
            for (var i = 0; i < count; i++) {
                if (get(i).pickerName === name) {
                    return i;
                }
            }
            return -1;
        }

        // the function checks whether a pickerModel is present in the list;
        // moves the existing one to the given index or inserts it if not present
        function setPickerModel(model, name, index) {
            var idx = pickerModelIndex(name);
            if (idx >= 0) {
                move(idx, index, 1);
            } else {
                append({"pickerModel": model, "pickerName": name});
            }
        }

        // removes the given picker
        function removePicker(name) {
            var idx = pickerModelIndex(name);
            if (idx >= 0) {
                pickerRemoved(idx);
                remove(idx);
            }
        }
    }

    // component to calculate text fitting
    Label { id: textSizer; visible: false }
    QtObject {
        id: internals
        property bool completed: false
        property real margin: units.gu(1.5)
        property real dayPickerRatio: 0.1

        property bool showYearPicker: true
        property bool showMonthPicker: true
        property bool showDayPicker: true

        property bool showHoursPicker: false
        property bool showMinutesPicker: false
        property bool showSecondsPicker: false

        /*
          Update pickers.
          */
        function updatePickers() {
            if (completed) {
                // check mode flags first
                // FIXME: The js split(/\W/g) terminates the process on armhf with Qt 5.3 (v4 js) (https://bugreports.qt-project.org/browse/QTBUG-39255)
                var modes = datePicker.mode.match(/\w+/g);

                showYearPicker = showMonthPicker = showDayPicker =
                showHoursPicker = showMinutesPicker = showSecondsPicker = false;
                while (modes.length > 0) {
                    var modeFlag = modes.pop();
                    switch (modeFlag) {
                    case "Years":
                        showYearPicker = true;
                        break;
                    case "Months":
                        showMonthPicker = true;
                        break;
                    case "Days":
                        showDayPicker = true;
                        break;
                    case "Hours":
                        showHoursPicker = true;
                        break;
                    case "Minutes":
                        showMinutesPicker = true;
                        break;
                    case "Seconds":
                        showSecondsPicker = true;
                        break;
                    default:
                        console.warn("Unhandled mode flag: " + modeFlag + ". Mode will not be set!");
                        return;
                    }
                }

                // filter unaccepted date picking mode
                if (!showMonthPicker && showYearPicker && showDayPicker) {
                    console.warn("Invalid DatePicker mode: " + datePicker.mode);
                    return;
                }

                // filter unaccepted time picking mode
                if (showHoursPicker && showSecondsPicker && !showMinutesPicker) {
                    console.warn("Invalid DatePicker mode: " + datePicker.mode);
                    return;
                }

                // date and time picking not allowed at the same time
                if ((showYearPicker || showMonthPicker || showDayPicker) &&
                        (showHoursPicker || showMinutesPicker || showSecondsPicker)) {
                    console.warn("Date and Time picking not allowed at the same time.");
                    return;
                }

                arrangeTumblers();
                resetPickers();
            }
        }

        /*
          Resets the pickers. Pickers will update their models with the given date,
          minimum and maximum values.
          */
        function resetPickers() {
            if (!completed) return;
            for (var i = 0; i < tumblerModel.count; i++) {
                var pickerItem = tumblerModel.get(i).pickerModel.pickerItem;
                pickerItem.resetPicker();
            }

            // calculate the ratio for the dayPicker
            var maxWidth = 0.0;
            maxWidth += showYearPicker ? yearModel.longFormatLimit : 0.0;
            maxWidth += showMonthPicker ? monthModel.longFormatLimit : 0.0;
            maxWidth += showDayPicker ? dayModel.longFormatLimit : 0.0;
            if (showDayPicker && maxWidth > 0.0) {
                dayPickerRatio = (dayModel.longFormatLimit / maxWidth).toPrecision(3);
            }
        }

        /*
            Detects the tumbler order from the date format of the locale
          */
        function arrangeTumblers() {
            // disable completion so avoid accidental date changes
            completed = false;

            // use short format to exclude any extra characters
            // FIXME: The js split(/\W/g) terminates the process on armhf with Qt 5.3 (v4 js) (https://bugreports.qt-project.org/browse/QTBUG-39255)
            var format = datePicker.locale.dateFormat(Locale.ShortFormat).match(/\w+/g);
            // loop through the format to decide the position of the tumbler
            var formatIndex = 0;
            for (var i in format) {
                if (!format[i].length) continue;
                // check the first two characters
                switch (format[i].substr(0, 1).toLowerCase()) {
                case 'y':
                    if (showYearPicker) {
                        tumblerModel.setPickerModel(yearModel, "YearPicker", formatIndex);
                        formatIndex++;
                    } else {
                        tumblerModel.removePicker("YearPicker");
                    }

                    break;
                case 'm':
                    if (showMonthPicker) {
                        tumblerModel.setPickerModel(monthModel, "MonthPicker", formatIndex);
                        formatIndex++;
                    } else {
                        tumblerModel.removePicker("MonthPicker");
                    }

                    break;
                case 'd':
                    if (showDayPicker) {
                        tumblerModel.setPickerModel(dayModel, "DayPicker", formatIndex);
                        formatIndex++;
                    } else {
                        tumblerModel.removePicker("DayPicker");
                    }
                    break;
                }
            }
            // check hms
            if (showHoursPicker) {
                tumblerModel.setPickerModel(hoursModel, "HoursPicker", formatIndex);
                formatIndex++;
            } else {
                tumblerModel.removePicker("HoursPicker");
            }
            if (showMinutesPicker) {
                tumblerModel.setPickerModel(minutesModel, "MinutesPicker", formatIndex);
                formatIndex++;
            } else {
                tumblerModel.removePicker("MinutesPicker");
            }
            if (showSecondsPicker) {
                tumblerModel.setPickerModel(secondsModel, "SecondsPicker", formatIndex);
                formatIndex++;
            } else {
                tumblerModel.removePicker("SecondsPicker");
            }

            // re-enable completion
            completed = true;
        }
    }
}