// Copyright (c) 2015 Piotr Tworek. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.YTPlayer file.

import QtQuick 2.0
import Sailfish.Silica 1.0

Image {
    fillMode: Image.PreserveAspectCrop

    property alias indicatorSize: indicator.size

    BusyIndicator {
        id: indicator
        size: BusyIndicatorSize.Small
        anchors.centerIn: parent
        running: parent.status === Image.Loading
    }

    Rectangle {
        anchors.fill: parent
        color: Theme.secondaryHighlightColor
        visible: status === Image.Error
        Label {
            anchors.centerIn: parent
            width: parent.width
            maximumLineCount: 1
            font.pixelSize: Theme.fontSizeExtraSmall
            horizontalAlignment: Text.AlignHCenter
            //: Label shown where video thumbnail is not valid, can't be loaded.
            //: Should be very short 8-10 characters max.
            //% "No image"
            text: qsTrId("ytplayer-label-broken-image")
            color: Theme.primaryColor
        }
    }
}

Tweak AyncImage to work with longer translation strings.

// Copyright (c) 2015 Piotr Tworek. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.YTPlayer file.

import QtQuick 2.0
import Sailfish.Silica 1.0

Image {
    fillMode: Image.PreserveAspectCrop

    property alias indicatorSize: indicator.size

    BusyIndicator {
        id: indicator
        size: BusyIndicatorSize.Small
        anchors.centerIn: parent
        running: parent.status === Image.Loading
    }

    Rectangle {
        anchors.fill: parent
        color: Theme.secondaryHighlightColor
        visible: status === Image.Error
        Label {
            anchors.fill: parent
            width: parent.width
            maximumLineCount: 1
            font.pixelSize: Theme.fontSizeExtraSmall
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            fontSizeMode: Text.HorizontalFit
            //: Label shown where video thumbnail is not valid, can't be loaded.
            //: Should be very short 8-10 characters max.
            //% "No image"
            text: qsTrId("ytplayer-label-broken-image")
            color: Theme.primaryColor
        }
    }
}


import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.12

ColumnLayout {
    id: root

    signal accepted(string source)
    signal rejected()

    property string currentSource
    property var sources

    ButtonGroup {
        id: buttonGroup
    }

    ListView {
        id: results
        Layout.fillWidth: true
        Layout.fillHeight: true
        model: sources

        delegate: RadioDelegate {
            width: parent.width
            checked: modelData == currentSource
            text: modelData
            ButtonGroup.group: buttonGroup
            height: 30 // from 40
            padding: 8 // from 12

            indicator: MiniRadioIndicator {
                control: parent
                size: 18 // from 28
            }

            onCheckedChanged: if (checked) currentSource = modelData
        }
    }

    DialogButtonBox {
        standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel
        Layout.fillWidth: true

        onAccepted: root.accepted(buttonGroup.checkedButton.text)
        onRejected: root.rejected()
    }
}

Improve looks of the sources selection screen

import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.12

Page {
    id: root

    signal accepted(string source)
    signal rejected()

    property string currentSource
    property var sources

    header: ToolBar {
        RowLayout {
            anchors.fill: parent

            ToolButton {
                icon.source: "/images/icons/back.png"
                onClicked: root.accepted(buttonGroup.checkedButton.text)
            }

            Label {
                text: "Sources selection"
                elide: Label.ElideRight
                horizontalAlignment: Qt.AlignHCenter
                verticalAlignment: Qt.AlignVCenter
                Layout.fillWidth: true
            }
        }
    }

    ButtonGroup {
        id: buttonGroup
    }

    ListView {
        id: results
        anchors.fill: parent
        model: sources

        delegate: RadioDelegate {
            width: parent.width
            checked: modelData == currentSource
            text: modelData
            ButtonGroup.group: buttonGroup
            height: 30 // from 40
            padding: 8 // from 12

            indicator: MiniRadioIndicator {
                control: parent
                size: 18 // from 28
            }

            onCheckedChanged: if (checked) currentSource = modelData
        }
    }
}


Item {
	constructor: {
		this._activityStack = []
	}

	push(name, intent, state): {
		this._activityStack.push({ "name": name, "intent": intent, "state": state })
		this.initTopIntent()
	}

	pop: {
		this._activityStack.pop()
		this.initTopIntent()
	}

	setState(state, idx): {
		this._activityStack[idx || this._activityStack.length - 1].state = state
	}

	initTopIntent: {
		if (!this._activityStack.length) {
			log("Activity stack is empty")
			return
		}

		var topActivity = this._activityStack[this._activityStack.length - 1]
		var children = this.children

		for (var i = 0; i < children.length; ++i) {
			var child = children[i]
			if (!child || !(child instanceof _globals.controls.core.Activity))
				continue

			child.visible = false
			if (child.name === topActivity.name) {
				log("Init:", topActivity)
				child.init(topActivity.intent, topActivity.state)
				child.index = this._activityStack.length - 1
				child.visible = true
				child.setFocus()
			}
		}
	}
}

Add 'count' property in activity manager

Item {
	property int count;

	constructor: {
		this._activityStack = []
	}

	push(name, intent, state): {
		this._activityStack.push({ "name": name, "intent": intent, "state": state })
		this.count++
		this.initTopIntent()
	}

	pop: {
		this._activityStack.pop()
		--this.count
		this.initTopIntent()
	}

	setState(state, idx): {
		this._activityStack[idx || this._activityStack.length - 1].state = state
	}

	initTopIntent: {
		if (!this._activityStack.length) {
			log("Activity stack is empty")
			return
		}

		var topActivity = this._activityStack[this._activityStack.length - 1]
		var children = this.children

		for (var i = 0; i < children.length; ++i) {
			var child = children[i]
			if (!child || !(child instanceof _globals.controls.core.Activity))
				continue

			child.visible = false
			if (child.name === topActivity.name) {
				log("Init:", topActivity)
				child.init(topActivity.intent, topActivity.state)
				child.index = this._activityStack.length - 1
				child.visible = true
				child.setFocus()
			}
		}
	}
}


import QtQuick 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1

import ".." as UM

ComboBox
{
    signal valueChanged(string value);

    model: options //From parent loader

    currentIndex: {
        for(var i = 0; i < options.rowCount(); ++i) {
            if(options.getItem(i).text == value /*From parent loader*/) {
                return i;
            }
        }

        return -1;
    }
    style: ComboBoxStyle {
        background: Rectangle {
            color: control.hovered ? itemStyle.controlHighlightColor : itemStyle.controlColor;
            border.width: itemStyle.controlBorderWidth;
            border.color: itemStyle.controlBorderColor;
        }
    }

    onCurrentIndexChanged: if (currentIndex != value) valueChanged(currentText);
}

Add a down arrow to the Setting combo box

import QtQuick 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1

import ".." as UM

ComboBox
{
    signal valueChanged(string value);

    model: options //From parent loader

    currentIndex: {
        for(var i = 0; i < options.rowCount(); ++i) {
            if(options.getItem(i).text == value /*From parent loader*/) {
                return i;
            }
        }

        return -1;
    }

    style: ComboBoxStyle {
        background: Rectangle {
            color: control.hovered ? itemStyle.controlHighlightColor : itemStyle.controlColor;
            border.width: itemStyle.controlBorderWidth;
            border.color: itemStyle.controlBorderColor;

            Label {
                anchors.right: parent.right;
                anchors.rightMargin: 5;
                anchors.verticalCenter: parent.verticalCenter;

                color: itemStyle.controlBorderColor;

                text: "▼";
            }
        }
    }

    onCurrentIndexChanged: if (currentIndex != value) valueChanged(currentText);
}


import QtQuick 2.2
import QtQuick.Controls 1.1

Menu {
	Menu {
		id:kcmNew

		title: qsTr("New")

		Menu {
			title: qsTr("Create here ...")

			MenuItem {
				id:kcmNewKey

				action: newKeyAction
			}
			MenuItem {
				id:kcmNewArray

				action: newArrayAction
			}

		}
		Menu {
			title: qsTr("Create below ...")

			MenuItem {
				id:kcmNewKeyBelow

				property string src: "keyBelow"

				action: newKeyAction
			}
			MenuItem {
				id:kcmNewArrayBelow

				property string src: "arrBelow"

				action: newArrayAction
			}
		}
	}
	MenuItem {
		id: kcmEdit
		action: editAction
	}
	MenuItem {
		id: kcmCut
		action: cutAction
	}
	MenuItem {
		id: kcmCopy
		action: copyAction
	}
	MenuItem {
		id: kcmPaste
		action: pasteAction
	}
	MenuItem {
		id: kcmDelete
		action: deleteAction
	}
}

Reduce depth of keyarea context menu

import QtQuick 2.2
import QtQuick.Controls 1.1

Menu {
	Menu {
		id:kcmNew

		title: qsTr("New")

		MenuItem {
			id:kcmNewKey

			action: newKeyAction
			text: qsTr("Create Key here ...")
		}
		MenuItem {
			id:kcmNewArray

			action: newArrayAction
			text: qsTr("Create Array Entry here ...")
		}
		MenuItem {
			id:kcmNewKeyBelow

			property string src: "keyBelow"

			action: newKeyAction
			text: qsTr("Create Key below ...")
		}
		MenuItem {
			id:kcmNewArrayBelow

			property string src: "arrBelow"

			action: newArrayAction
			text: qsTr("Create Array Entry below ...")
		}
	}
	MenuItem {
		id: kcmEdit
		action: editAction
	}
	MenuItem {
		id: kcmCut
		action: cutAction
	}
	MenuItem {
		id: kcmCopy
		action: copyAction
	}
	MenuItem {
		id: kcmPaste
		action: pasteAction
	}
	MenuItem {
		id: kcmDelete
		action: deleteAction
	}
}


import qbs 1.0

import QtcPlugin

QtcPlugin {
    name: "UpdateInfo"

    Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] }
    Depends { name: "Utils" }

    Depends { name: "Core" }

    property bool enable: false
    pluginJsonReplacements: ({"UPDATEINFO_EXPERIMENTAL_STR": (enable ? "false": "true")})

    files: [
        "updateinfobutton.cpp",
        "updateinfobutton.h",
        "updateinfoplugin.cpp",
        "updateinfoplugin.h",
        "settingspage.cpp",
        "settingspage.h",
        "settingspage.ui",
    ]
}

Disable UpdateInfo plugin also with qbs build.

import qbs 1.0

import QtcPlugin

QtcPlugin {
    name: "UpdateInfo"

    condition: false // Severely broken atm.

    Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] }
    Depends { name: "Utils" }

    Depends { name: "Core" }

    property bool enable: false
    pluginJsonReplacements: ({"UPDATEINFO_EXPERIMENTAL_STR": (enable ? "false": "true")})

    files: [
        "updateinfobutton.cpp",
        "updateinfobutton.h",
        "updateinfoplugin.cpp",
        "updateinfoplugin.h",
        "settingspage.cpp",
        "settingspage.h",
        "settingspage.ui",
    ]
}


Item {
	property string code;
	property string language;
	property Font font: Font {}
	clip: true;

	function _update(name, value) {
		switch (name) {
			case 'width':		this._updateSize(); break
			case 'height':		this._updateSize(); break
			case 'code':		this._code.dom.innerHTML = value; window.hljs.highlightBlock(this._code.dom); break
			case 'language':	this._code.dom.className = value; window.hljs.highlightBlock(this._code.dom); break
		}
		_globals.core.Item.prototype._update.apply(this, arguments);
	}

	constructor: {
		if (!window.hljs) {
			log("hljs is not defined! Maybe you forget to attach highlight.js file.")
			return
		}
		this.element.remove()
		this.element = this._context.createElement('pre')
		this._code = this._context.createElement('code')
		this._code.dom.style.width = "inherit"
		this._code.dom.style.height = "inherit"
		this._code.dom.style.font = "inherit"
		this.element.append(this._code)
		this.parent.element.append(this.element)
	}

	function _updateSize() {
		var style = { width: this.width, height: this.height }
		this.style(style)
	}
}

Add property for setting height according its content.

Item {
	property bool fitToContent: false;
	property string code;
	property string language;
	property Font font: Font {}
	clip: true;

	function _update(name, value) {
		switch (name) {
			case 'width':		this._updateSize(); break
			case 'height':		this._updateSize(); break
			case 'code':		this._code.dom.innerHTML = value; window.hljs.highlightBlock(this._code.dom); break
			case 'language':	this._code.dom.className = value; window.hljs.highlightBlock(this._code.dom); break
			case 'fitToContent': this._code.dom.style.height = value ? "auto" : "inherit"; break
		}
		_globals.core.Item.prototype._update.apply(this, arguments);
	}

	constructor: {
		if (!window.hljs) {
			log("hljs is not defined! Maybe you forget to attach highlight.js file.")
			return
		}
		this.element.remove()
		this.element = this._context.createElement('pre')
		this._code = this._context.createElement('code')
		this._code.dom.style.width = "inherit"
		this._code.dom.style.height = "inherit"
		this._code.dom.style.font = "inherit"
		this.element.append(this._code)
		this.parent.element.append(this.element)
	}

	function _updateSize() {
		if (this.fitToContent)
			this.height = this._code.dom.scrollHeight
		var style = { width: this.width, height: this.height }
		this.style(style)
	}
}


import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2

ColumnLayout {
    id: header
    spacing: 0
    height: 63
    Rectangle {
        id: background
        Layout.minimumHeight: 60
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#ffffff"
        Image {
            id: logo
            width: 100
            height: 28
            anchors.left: parent.left
            anchors.leftMargin: 5
            anchors.bottomMargin: 5
            anchors.bottom: parent.bottom
            source: "../images/logo-header.png"
        }
    }
    Rectangle {
        id: headerBorder
        Layout.minimumHeight: 3
        Layout.maximumHeight: 3
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#9aca3c"
    }
}

Update margins a bit, support resizing better

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2

ColumnLayout {
    id: header
    spacing: 0
    Layout.maximumHeight: 63
    Layout.minimumHeight: 63
    Layout.alignment: Qt.AlignLeft | Qt.AlignTop
    Rectangle {
        id: background
        Layout.minimumHeight: 60
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#ffffff"
        Image {
            id: logo
            width: 100
            height: 28
            anchors.left: parent.left
            anchors.leftMargin: 12
            anchors.bottomMargin: 5
            anchors.bottom: parent.bottom
            source: "../images/logo-header.png"
        }
    }
    Rectangle {
        id: headerBorder
        Layout.minimumHeight: 3
        Layout.maximumHeight: 3
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#9aca3c"
    }
}


/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7

Item {
    id: avatar

    property bool active: true
    property alias source: avatarImage.source
    property alias noAvatarImage: noAvatar.source

    width: childrenRect.width
    height:  parent.height

    Image {
        id: avatarImage

        anchors.fill: avatarItem

        fillMode: Image.PreserveAspectFit

        visible: (source != ""? true : false)
        onStatusChanged: {
            if(status == Image.Error) {
                avatarImage.visible = false;
            }
        }
    }

    Item {
        id: avatarItem
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.margins: 2
        width: height
    }

    BorderImage {
        id: avatarBorder

        anchors.fill: avatarImage

        visible: avatarImage.visible

        source: (active ?
                     "image://themedimage/widgets/common/avatar/avatar-shadow" :
                     "image://themedimage/widgets/common/avatar/avatar-inactive-overlay")
    }

    BorderImage {
        id: noAvatar
        anchors.fill: avatarImage
        source: "image://themedimage/widgets/common/avatar/avatar-default"
        visible: !avatarImage.visible
    }
}

Make sure the avatar is visible when the image is successfully loaded. This solves an issue when an avatar had a previous error.

/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7

Item {
    id: avatar

    property bool active: true
    property alias source: avatarImage.source
    property alias noAvatarImage: noAvatar.source

    width: childrenRect.width
    height:  parent.height

    Image {
        id: avatarImage

        anchors.fill: avatarItem

        fillMode: Image.PreserveAspectFit

        visible: (source != ""? true : false)
        onStatusChanged: {
            if (status == Image.Error) {
                avatarImage.visible = false;
            } else if (status == Image.Ready) {
                avatarImage.visible = true;
            }
        }
    }

    Item {
        id: avatarItem
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.margins: 2
        width: height
    }

    BorderImage {
        id: avatarBorder

        anchors.fill: avatarImage

        visible: avatarImage.visible

        source: (active ?
                     "image://themedimage/widgets/common/avatar/avatar-shadow" :
                     "image://themedimage/widgets/common/avatar/avatar-inactive-overlay")
    }

    BorderImage {
        id: noAvatar
        anchors.fill: avatarImage
        source: "image://themedimage/widgets/common/avatar/avatar-default"
        visible: !avatarImage.visible
    }
}


Add a component for drawing a rectangle with a hole in it

/*
 * Copyright (C) 2015 Vishesh Handa <vhanda@kde.org>
 *
 * This library 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; either
 * version 2.1 of the License, or (at your option) version 3, or any
 * later version accepted by the membership of KDE e.V. (or its
 * successor approved by the membership of KDE e.V.), which shall
 * act as a proxy defined in Section 6 of version 3 of the license.
 *
 * This library 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 library.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

import QtQuick 2.3

/**
 * @brief Renders a rectangle of a solid color, with a hole somewhere inside it
 */
Item {
    id: component
    /**
     * The height of the top border (distance from the top edge to the beginning of the hole)
     */
    property alias topBorder: topRect.height
    /**
     * The width of the left hand side border (distance from the left edge to the beginning of the hole)
     */
    property alias leftBorder: leftRect.width
    /**
     * The width of the right hand side border (distance from the right edge to the beginning of the hole)
     */
    property alias rightBorder: rightRect.width
    /**
     * The height of the bottom border (distance from the bottom edge to the beginning of the hole)
     */
    property alias bottomBorder: bottomRect.height
    /**
     * The color of the rectangle, around the hole
     */
    property alias color: topRect.color

    function setHole(holeRect) {
        component.topBorder = holeRect.y;
        component.leftBorder = holeRect.x;
        component.rightBorder = component.width - (holeRect.x + holeRect.width);
        component.bottomBorder = component.height - (holeRect.y + holeRect.height);
    }

    Rectangle {
        id: topRect
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
        }
    }
    Rectangle {
        id: leftRect
        anchors {
            top: parent.top
            left: parent.left
            bottom: parent.bottom
        }
        color: topRect.color
    }
    Rectangle {
        id: rightRect
        anchors {
            top: parent.top
            right: parent.right
            bottom: parent.bottom
        }
        color: topRect.color
    }
    Rectangle {
        id: bottomRect
        anchors {
            left: parent.left
            right: parent.right
            bottom: parent.bottom
        }
        color: topRect.color
    }
}


// Copyright (c) 2015 Ableton AG, Berlin
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

import QtQuick 2.3
import Aqt.Cassowary 1.0

Edit {
    id: edit
    suggested: actualTarget.value
    strength: Strength.Weak
}

Fix warning when stais don't have a target

// Copyright (c) 2015 Ableton AG, Berlin
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

import QtQuick 2.3
import Aqt.Cassowary 1.0

Edit {
    id: edit
    suggested: actualTarget ? actualTarget.value : NaN
    strength: Strength.Weak
}


// Copyright (c) 2020 Aldo Hoeben / fieldOfView
// OctoPrintPlugin is released under the terms of the AGPLv3 or higher.

import UM 1.2 as UM
import Cura 1.0 as Cura

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1

Item
{
    id: base

    property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
    property bool octoPrintConnected: printerConnected && Cura.MachineManager.printerOutputDevices[0].hasOwnProperty("octoprintVersion")

    Button
    {
        objectName: "openOctoPrintButton"
        height: UM.Theme.getSize("save_button_save_to_button").height
        tooltip: catalog.i18nc("@info:tooltip", "Open the OctoPrint web interface")
        text: catalog.i18nc("@action:button", "OctoPrint...")
        style: UM.Theme.styles.sidebar_action_button
        onClicked: manager.openWebPage(Cura.MachineManager.printerOutputDevices[0].baseURL)
        visible: octoPrintConnected
    }

    UM.I18nCatalog{id: catalog; name:"cura"}
}

Fix OctoPrint... button in print monitor

// Copyright (c) 2020 Aldo Hoeben / fieldOfView
// OctoPrintPlugin is released under the terms of the AGPLv3 or higher.

import UM 1.2 as UM
import Cura 1.0 as Cura

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1

Item
{
    id: base

    property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
    property bool octoPrintConnected: printerConnected && Cura.MachineManager.printerOutputDevices[0].hasOwnProperty("octoprintVersion")

    Button
    {
        objectName: "openOctoPrintButton"
        height: UM.Theme.getSize("save_button_save_to_button").height
        tooltip: catalog.i18nc("@info:tooltip", "Open the OctoPrint web interface")
        text: catalog.i18nc("@action:button", "OctoPrint...")
        style:
        {
            if(UM.Theme.styles.hasOwnProperty("print_setup_action_button")) {
                return UM.Theme.styles.print_setup_action_button
            }
            else
            {
                return UM.Theme.styles.sidebar_action_button
            }
        }
        onClicked: manager.openWebPage(Cura.MachineManager.printerOutputDevices[0].baseURL)
        visible: octoPrintConnected
    }

    UM.I18nCatalog{id: catalog; name:"cura"}
}


/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7
import MeeGo.Panels 0.1

SecondaryTile {
    id: fpMusicPreview

    property bool imagePlayStatus: false

    property bool isCurrentlyPlayingLayout: false
    signal backButtonClicked()
    signal playButtonClicked()
    signal forwardButtonClicked()

    mouseAreaActive: true
    zoomImage: true
    fallBackImage: "image://theme/media/music_thumb_med"
    imageComponent: imageAlbum
    imageChildComponent: playPauseComponent
    Component {
        id: playPauseComponent
        Image{
            id: playPauseButton
            anchors.verticalCenter: parent.verticalCenter
            anchors.horizontalCenter: parent.horizontalCenter
            // TODO: get right size images
            height: parent ? parent.height : 0
            width: width
            fillMode: Image.PreserveAspectFit
            smooth: true
            source: imagePlayStatus?"image://themedimage/images/panels/pnl_btn_pause_up"
            :"image://themedimage/images/panels/pnl_btn_play_up"
            MouseArea {
                anchors.fill: parent
                onPressAndHold: {
                    var posInItem = fpMusicPreview.mapFromItem(playPauseButton, mouse.x, mouse.y);
                    fpMusicPreview.pressAndHold(posInItem);
                }
                onClicked: {
                    fpMusicPreview.playButtonClicked();
                }
            }
        }
    }
}

Rebase fix: image provider theme => themedimage

/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7
import MeeGo.Panels 0.1

SecondaryTile {
    id: fpMusicPreview

    property bool imagePlayStatus: false

    property bool isCurrentlyPlayingLayout: false
    signal backButtonClicked()
    signal playButtonClicked()
    signal forwardButtonClicked()

    mouseAreaActive: true
    zoomImage: true
    fallBackImage: "image://themedimage/images/media/music_thumb_med"
    imageComponent: imageAlbum
    imageChildComponent: playPauseComponent
    Component {
        id: playPauseComponent
        Image{
            id: playPauseButton
            anchors.verticalCenter: parent.verticalCenter
            anchors.horizontalCenter: parent.horizontalCenter
            // TODO: get right size images
            height: parent ? parent.height : 0
            width: width
            fillMode: Image.PreserveAspectFit
            smooth: true
            source: imagePlayStatus?"image://themedimage/images/panels/pnl_btn_pause_up"
            :"image://themedimage/images/panels/pnl_btn_play_up"
            MouseArea {
                anchors.fill: parent
                onPressAndHold: {
                    var posInItem = fpMusicPreview.mapFromItem(playPauseButton, mouse.x, mouse.y);
                    fpMusicPreview.pressAndHold(posInItem);
                }
                onClicked: {
                    fpMusicPreview.playButtonClicked();
                }
            }
        }
    }
}


import qbs

Project {
	qbsSearchPaths: ['project/qbs']

 	references: [
	    "emulator/emulator.qbs",
 	    "libtee/libtee.qbs",
            "tests/tests.qbs",
            "CAs/ClientApplications.qbs",
            "TAs/TrustedApplications.qbs",
	    "libtee_pkcs11/libtee_pkcs11.qbs"
	]
}

Add conditional include of omnishare

import qbs
import qbs.File

Project {
    qbsSearchPaths: ['project/qbs']

    references: {
        var binaries = [
                    "emulator/emulator.qbs",
                    "libtee/libtee.qbs",
                    "tests/tests.qbs",
                    "CAs/ClientApplications.qbs",
                    "TAs/TrustedApplications.qbs",
                    "libtee_pkcs11/libtee_pkcs11.qbs"
                ]

        if (File.exists(sourceDirectory + "/libomnishare/libomnishare.qbs")) {
            binaries.push("libomnishare/libomnishare.qbs")
        }
        return binaries
    }
}


import Qt 4.6

Grid {
    id: myGrid

    width: 270
    height: 270
    x: 3
    y: 3
    columns: 4
    spacing: 3

    add: columnTransition
    move: columnTransition

    Repeater {
        model: 20
        Rectangle { color: "black"; width: 50; height: 50 }
    }

    data: [
    Transition {
        id: rowTransition
        objectName: "rowTransition"
        NumberAnimation {
            properties: "x,y";
            easing: "easeOutInCubic"
        }
    },
    Transition {
        id: columnTransition
        objectName: "columnTransition"
        NumberAnimation {
            properties: "x,y";
            easing: "easeOutInCubic"
        }
    }
    ]
}

Fix positioner auto test with new easing curve syntax

import Qt 4.6

Grid {
    id: myGrid

    width: 270
    height: 270
    x: 3
    y: 3
    columns: 4
    spacing: 3

    add: columnTransition
    move: columnTransition

    Repeater {
        model: 20
        Rectangle { color: "black"; width: 50; height: 50 }
    }

    data: [
    Transition {
        id: rowTransition
        objectName: "rowTransition"
        NumberAnimation {
            properties: "x,y";
            easing.type: "OutInCubic"
        }
    },
    Transition {
        id: columnTransition
        objectName: "columnTransition"
        NumberAnimation {
            properties: "x,y";
            easing.type: "OutInCubic"
        }
    }
    ]
}


// Copyright (c) 2015 Ultimaker B.V.
// Uranium is released under the terms of the AGPLv3 or higher.

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1

import UM 1.0 as UM

Button {
    id: base;

    Layout.preferredHeight: UM.Theme.sizes.section.height;
    Layout.preferredWidth: UM.Theme.sizes.sidebar.width;

    property variant color;
    style: UM.Theme.styles.sidebar_category;

    Button{
        id: settingsButton
        visible: base.hovered || settingsButton.hovered
        height: base.height * 0.6
        width: base.height * 0.6
        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right
        anchors.rightMargin: UM.Theme.sizes.setting_preferences_button_margin.width
        style: ButtonStyle {
            background: UM.RecolorImage {
                id: settingsImage
                width: control.width
                height: control.height
                sourceSize.width: width
                sourceSize.height: width
                color: control.hovered ? UM.Theme.colors.setting_control_button_hover : UM.Theme.colors.setting_control_button
                source: UM.Theme.icons.settings
            }
            label: Label{}
        }
        onClicked: {
            preferences.visible = true;
            preferences.setPage(2);
            preferences.getCurrentItem().scrollToSection(model.id);
        }
    }
}

Replace Button with a MouseArea

// Copyright (c) 2015 Ultimaker B.V.
// Uranium is released under the terms of the AGPLv3 or higher.

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1

import UM 1.0 as UM

Button {
    id: base;

    property variant color;

    style: UM.Theme.styles.sidebar_category;

    MouseArea {
        id: settingsButton

        visible: base.hovered || settingsButton.hovered
        height: base.height * 0.6
        width: base.height * 0.6

        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right
        anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width

        UM.RecolorImage {
            anchors.fill: parent;

            sourceSize.width: width
            sourceSize.height: width

            color: parent.containsMouse ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button");
            source: UM.Theme.getIcon("settings");
        }

        onClicked: {
            preferences.visible = true;
            preferences.setPage(2);
            preferences.getCurrentItem().scrollToSection(model.id);
        }
    }
}


/****************************************************************************
 * This file is part of Qt AccountsService Addon.
 *
 * Copyright (C) 2015 Leslie Zhai <xiang.zhai@i-soft.com.cn>
 *
 * Author(s):
 *    Leslie Zhai
 *
 * $BEGIN_LICENSE:LGPL2.1+$
 *
 * 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, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * 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/>.
 *
 * $END_LICENSE$
 ***************************************************************************/

import QtQuick 2.2
import QtQuick.Window 2.1
import QtAccountsService 1.0

Window {
    width: 300; height: 200
    title: "AccountsService Qt binding"

    UserAccount {
        id: userAccount
        Component.onCompleted: {
            faceIcon.source = iconFileName;
            loginName.text = userName;
            displayName.text = userAccount.displayName;
        }
    }

    Image {
        id: faceIcon
    }

    Text {
        id: loginName
        anchors.left: faceIcon.right
    }

    Text {
        id: displayName
        anchors.top: loginName.bottom
        anchors.left: loginName.left
    }
}


import qbs
import qbs.TextFile

MyApplication {
    name: "myapp"
    type: base.concat("extra-output")
    files: "main.cpp"
    Group {
        fileTagsFilter: "application"
        qbs.installDir: "binDir"
        fileTags: "extra-input"
    }
    Rule {
        inputs: "extra-input"
        Artifact {
            filePath: input.fileName + ".txt"
            fileTags: "extra-output"
        }
        prepare: {
            var cmd = new JavaScriptCommand();
            cmd.description = "creating " + output.fileName;
            cmd.sourceCode = function() {
                var f = new TextFile(output.filePath, TextFile.WriteOnly);
                f.close();
            }
            return cmd;
        }
    }
}

Fix fileTagsFilterMerging autotest on Windows

import qbs
import qbs.TextFile

MyApplication {
    name: "myapp"
    type: base.concat("extra-output")
    files: "main.cpp"
    Group {
        fileTagsFilter: "application"
        qbs.installDir: "binDir"
        fileTags: "extra-input"
    }
    Rule {
        inputs: "extra-input"
        Artifact {
            filePath: input.baseName + ".txt"
            fileTags: "extra-output"
        }
        prepare: {
            var cmd = new JavaScriptCommand();
            cmd.description = "creating " + output.fileName;
            cmd.sourceCode = function() {
                var f = new TextFile(output.filePath, TextFile.WriteOnly);
                f.close();
            }
            return cmd;
        }
    }
}


import Qt 4.7

Rectangle {
    border.width: 1
    border.color: "black"

    Component {
        id: conversationDelegate

        Text {
            text: {
                var time = Qt.formatTime(model.time, "hh:mm:ss");
                "[" + time + "] " + model.sender + ": " + model.text;
            }
        }
    }

    ListView {
        id: conversation
        anchors.fill: parent

        model: conversationModel
        delegate: conversationDelegate
    }
}

Add avatar to chat delegate in ConversationModel example.

import Qt 4.7

Rectangle {
    border.width: 1
    border.color: "black"

    Component {
        id: conversationDelegate

        Rectangle {
            height: childrenRect.height + 8
            width: parent.width

            Image {
                id: avatar
                width: 24
                height: 24
                anchors.left: parent.left
                anchors.top: parent.top

                source: model.senderAvatarUrl
            }
            Text {
                id: message
                anchors.left: avatar.right
                anchors.leftMargin: 4
                anchors.top: parent.top
                text: {
                    var time = Qt.formatTime(model.time, "hh:mm:ss");
                    "[" + time + "] " + model.sender + ": " + model.text;
                }
            }
        }
    }

    ListView {
        id: conversation
        anchors.fill: parent
        anchors.margins: 5

        model: conversationModel
        delegate: conversationDelegate
    }
}


import QtMultimedia 5.12
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.12

ColumnLayout {
    property alias source: video.source
    property alias fillMode: video.fillMode
    property alias autoPlay: video.autoPlay

    onAutoPlayChanged: {
        if (autoPlay && video.playbackState != MediaPlayer.PlayingState) {
            video.play()
        }
    }

    Video {
        id: video

        Layout.fillHeight: true
        Layout.fillWidth: true
        notifyInterval: 100
        loops: MediaPlayer.Infinite
    }

    RowLayout {
        Layout.fillWidth: true

        ToolButton {
            icon.source: video.playbackState == MediaPlayer.PlayingState ? "/images/icons/pause.png" : "/images/icons/play.png"
            onClicked: video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play()
        }

        Slider {
            from: 0
            to: video.duration
            live: false
            value: video.position
            Layout.fillWidth: true

            onValueChanged: if (value !== video.position) video.seek(value)
        }
    }
}

Add 100ms error for video slider jumps

import QtMultimedia 5.12
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.12

ColumnLayout {
    property alias source: video.source
    property alias fillMode: video.fillMode
    property alias autoPlay: video.autoPlay

    onAutoPlayChanged: {
        if (autoPlay && video.playbackState != MediaPlayer.PlayingState) {
            video.play()
        }
    }

    Video {
        id: video

        Layout.fillHeight: true
        Layout.fillWidth: true
        notifyInterval: 100
        loops: MediaPlayer.Infinite
    }

    RowLayout {
        Layout.fillWidth: true

        ToolButton {
            icon.source: video.playbackState == MediaPlayer.PlayingState ? "/images/icons/pause.png" : "/images/icons/play.png"
            onClicked: video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play()
        }

        Slider {
            from: 0
            to: video.duration
            live: false
            value: video.position
            Layout.fillWidth: true

            onValueChanged: if (Math.abs(value - video.position) > 100) video.seek(value)
        }
    }
}


import QtQuick 2.8
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.4
import org.kde.plasma.components 3.0 as PC
import "controls"

ColumnLayout {
    spacing: 1
    Layout.margins: units.smallSpacing
    Layout.preferredWidth: parent.width

    property bool showTrackSlider: true
    property bool showVolumeSlider: true
    property bool showStopButton: true
    // playback controls
    RowLayout {
        spacing: 1

        PC.ToolButton {
            icon.name: 'configure'
            onClicked: zoneMenu.open(this)
        }

        PrevButton { Layout.leftMargin: 15 }
        PlayPauseButton {}
        StopButton { visible: showStopButton }
        NextButton {}
        VolumeControl { showSlider: showVolumeSlider }
    }
    // track pos
    TrackPosControl {
        showSlider: showTrackSlider
        showLabel: showTrackSlider
    }
}

Remove track pos control, reformat layouts

import QtQuick 2.8
import QtQuick.Layouts 1.3
import org.kde.plasma.components 3.0 as PC
import "controls"

// playback controls
RowLayout {
    property bool showVolumeSlider: true
    property bool showStopButton: true

    spacing: 0

    PC.ToolButton {
        icon.name: 'configure'
        onClicked: zoneMenu.open(this)
    }
    PrevButton {}
    PlayPauseButton {}
    StopButton { visible: showStopButton }
    NextButton {}
    VolumeControl { showSlider: showVolumeSlider }
}


import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.0
import OperationCatalogModel 1.0
import OperationsByKeyModel 1.0
import OperationModel 1.0
import "../controls" as Controls
import "../Global.js" as Global

Item {
    id : operationCatTab
    anchors.fill: parent

    signal makeForm(string objectid, string name)

    ListView{
        id : operationsByKey
        anchors.fill: parent
        model : operations.operationKeywords
        delegate: Controls.CollapsiblePanel {
            id : keylistdelegate
            width : parent.width
            titleText: keyword
            headerHeight: 20
            panelHeight: 35 * operationCount
            state : "collapsed"
            headerColor: Math.floor(index/5) % 2 == 0 ? Global.alternatecolor1 : Global.alternatecolor3

            OperationList{
                id : operList
                operationsModel: operationsList
                width : parent.width
                height : parent.height
                parent : keylistdelegate.expandableArea
                byKey : true

                Connections{
                    target : operList
                    onMakeForm :{
                        makeForm(objectid,name)
                    }
                }
            }

            clip : true
        }
    }

}

Add url to signal makeForm

import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.0
import OperationCatalogModel 1.0
import OperationsByKeyModel 1.0
import OperationModel 1.0
import "../controls" as Controls
import "../Global.js" as Global

Item {
    id : operationCatTab
    anchors.fill: parent

    signal makeForm(string objectid, string name, string url)

    ListView{
        id : operationsByKey
        anchors.fill: parent
        model : operations.operationKeywords
        delegate: Controls.CollapsiblePanel {
            id : keylistdelegate
            width : parent.width
            titleText: keyword
            headerHeight: 20
            panelHeight: 35 * operationCount
            state : "collapsed"
            headerColor: Math.floor(index/5) % 2 == 0 ? Global.alternatecolor1 : Global.alternatecolor3

            OperationList{
                id : operList
                operationsModel: operationsList
                width : parent.width
                height : parent.height
                parent : keylistdelegate.expandableArea
                byKey : true

                Connections{
                    target : operList
                    onMakeForm :{
                        makeForm(objectid,name, url)
                    }
                }
            }

            clip : true
        }
    }

}


import QtQuick.Controls 1.0

ApplicationWindow {
    id : appWindow
    // for now, we are in landscape when using Controls
    property bool inPortrait : appWindow.width < appWindow.height
    //property bool inPortrait : false

    //property alias initialPage : pageStack.initialItem
    property alias pageStack : pageStack

    StackView {
        anchors.fill : parent
        id : pageStack
    }

    function pushPage(pageInstance, pageProperties, animate) {
        pageStack.push(pageInstance, pageProperties, animate)
        return pageInstance
    }
}

Fix the animate argument semantics

import QtQuick.Controls 1.0

ApplicationWindow {
    id : appWindow
    // for now, we are in landscape when using Controls
    property bool inPortrait : appWindow.width < appWindow.height
    //property bool inPortrait : false

    //property alias initialPage : pageStack.initialItem
    property alias pageStack : pageStack

    StackView {
        anchors.fill : parent
        id : pageStack
    }

    function pushPage(pageInstance, pageProperties, animate) {
        // the Controls page stack disables animations when
        // false is passed as the third argument, but we want to
        // have a more logical interface, so just invert the value
        // before passing it to the page stack
        pageStack.push(pageInstance, pageProperties, !animate)
        return pageInstance
    }
}


import QtQuick 2.0
import QtGraphicalEffects 1.0
import "." as QML

Rectangle {
  id : canvas
  anchors.fill: parent
  color: "black"

  Repeater {
      model: Math.round(Math.random()*200)+60
     QML.Firefly {
       parent: canvas
       x: Math.round(Math.random()*canvas.width)
       y: Math.round(Math.random()*canvas.height)
     }
  }  //end of Repeater

} //end of canvas rectangle

Make the number of fireflies scale a bit better with the size of the screen

import QtQuick 2.0
import QtGraphicalEffects 1.0
import "." as QML

Rectangle {
  id : canvas
  anchors.fill: parent
  color: "black"

  Repeater {
      model: Math.round(Math.random()*canvas.width/10)+100
     QML.Firefly {
       parent: canvas
       x: Math.round(Math.random()*canvas.width)
       y: Math.round(Math.random()*canvas.height)
     }
  }  //end of Repeater

} //end of canvas rectangle


// A dummy QML to import required package for qmlimportscanner

import QtQuick.Controls 1.2
import QtQml.Models 2.1
import QtGraphicalEffects 1.0

QtObject {

}

Fix a broken test case

// A dummy QML to import required package for qmlimportscanner
import QtQuick 2.0
import QtQuick.Controls 1.2
import QtQml.Models 2.1
import QtGraphicalEffects 1.0

QtObject {

}


/// iframe item to embed other page
Item {
	property string source;		///< another page source URL

	///@private
	function getTag() { return 'iframe' }

	onSourceChanged: { this.element.dom.src = value; }
}

Update 'source' property if iframe was reloaded + add 'loaded' signal

/// iframe item to embed other page
Item {
	signal loaded;				///< page was loaded signal
	property string source;		///< another page source URL

	///@private
	function getTag() { return 'iframe' }

	onSourceChanged: { this.element.dom.src = value; }

	constructor: {
		var self = this
		this.element.dom.onload = function() { self.source = this.src; self.loaded() }
	}
}


<Flickable width="{250*.75}" height="240"
    viewportWidth="{Web.width*Web.scale}" viewportHeight="{Web.height*Web.scale}">
<WebView id="Web" width="250" height="420" scale="0.75">
    <![CDATA[

        These are QML plugins, shown in a QML WebView via HTML OBJECT tags, all scaled to 75%
        and placed in a Flickable area...

Duration Color Plugin

500      red   <OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=500 color=red />

2000     blue  <OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=2000 color=blue />

1000     green <OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=1000 color=green />

    ]]>
</WebView>
</Flickable>

Enable plugins They're no longer on by default, as per QWebPage.

<Flickable width="{250*.75}" height="240"
    viewportWidth="{Web.width*Web.scale}" viewportHeight="{Web.height*Web.scale}">
<WebView id="Web" width="250" height="420" scale="0.75" settings.pluginsEnabled="true">
    <![CDATA[

        These are QML plugins, shown in a QML WebView via HTML OBJECT tags, all scaled to 75%
        and placed in a Flickable area...

Duration Color Plugin

500      red   <OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=500 color=red />

2000     blue  <OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=2000 color=blue />

1000     green <OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=1000 color=green />

    ]]>
</WebView>
</Flickable>


import QtQuick 2.0
import Sailfish.Silica 1.0
import "pages"

ApplicationWindow
{
    initialPage: DirectoryPage { }

    cover: CoverBackground {
        CoverPlaceholder {
            id: coverPlaceholder
            text: "File Browser"
            icon.source: "images/harbour-file-browser.png"
        }
    }
}

Remove warning "specifying an object instance for initialPage is sub-optimal"

import QtQuick 2.0
import Sailfish.Silica 1.0
import "pages"

ApplicationWindow
{
    initialPage: Component {
        DirectoryPage { }
    }

    cover: CoverBackground {
        CoverPlaceholder {
            id: coverPlaceholder
            text: "File Browser"
            icon.source: "images/harbour-file-browser.png"
        }
    }
}


import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import QtQuick.Controls.Material 2.2

ChangePinView {

    breadcrumbs: [{
            text: qsTr("PUK")
        }, {
            text: qsTr("Configure PINs")
        }, {
            text: qsTr("PUK")
        }]
    codeName: qsTr("PUK")
    defaultCurrentPin: constants.pivDefaultPuk
    hasCurrentPin: true
    maxLength: constants.pivPukMaxLength
    minLength: constants.pivPukMinLength

    onChangePin: {
        yubiKey.piv_change_puk(currentPin, newPin, function (resp) {
            if (resp.success) {
                pivSuccessPopup.open()
                views.pop()
            } else {
                if (resp.error === 'blocked') {
                    pivError.show(qsTr("PUK is blocked."))
                    views.pop()
                } else if (resp.error === 'wrong puk') {
                    clearCurrentPinInput()
                    pivError.show(
                                qsTr("Wrong current PUK. Tries remaning: %1").arg(
                                    resp.tries_left))
                } else if (resp.message) {
                    pivError.show(
                                qsTr("PUK change failed for an unknown reason. Error message: %1").arg(
                                    resp.message))
                } else {
                    pivError.show(
                                qsTr(
                                    "PUK change failed for an unknown reason."))
                }
            }
        })
    }
}

Fix old reference to yubiKey.piv_change_puk

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2
import QtQuick.Controls.Material 2.2

ChangePinView {

    breadcrumbs: [{
            text: qsTr("PUK")
        }, {
            text: qsTr("Configure PINs")
        }, {
            text: qsTr("PUK")
        }]
    codeName: qsTr("PUK")
    defaultCurrentPin: constants.pivDefaultPuk
    hasCurrentPin: true
    maxLength: constants.pivPukMaxLength
    minLength: constants.pivPukMinLength

    onChangePin: {
        yubiKey.pivChangePuk(currentPin, newPin, function (resp) {
            if (resp.success) {
                pivSuccessPopup.open()
                views.pop()
            } else {
                if (resp.error === 'blocked') {
                    pivError.show(qsTr("PUK is blocked."))
                    views.pop()
                } else if (resp.error === 'wrong puk') {
                    clearCurrentPinInput()
                    pivError.show(
                                qsTr("Wrong current PUK. Tries remaning: %1").arg(
                                    resp.tries_left))
                } else if (resp.message) {
                    pivError.show(
                                qsTr("PUK change failed for an unknown reason. Error message: %1").arg(
                                    resp.message))
                } else {
                    pivError.show(
                                qsTr(
                                    "PUK change failed for an unknown reason."))
                }
            }
        })
    }
}


/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7

Column {
    width: parent.width
    height: topBarBackground.height + topBarShadow.height

    Image {
        id: topBarBackground

        width: parent.width

        source: {
            if (orientation == 1 || orientation == 3) {
                return "image://theme/titlebar_l";
            } else {
                return "image://theme/titleBar_p";
            }
        }

        ToggleSwitch {
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
            state: camera.state
            onToggled: {
                camera.state = state;
            }
        }

        PhotoReviewBin {
            id: reviewBin
            x: parent.width - width
            anchors.verticalCenter: parent.verticalCenter
            source: camera.imageLocation

            onClicked: {
                if (reviewBin.type == "photo") {
                    processLauncher.launch ("meego-qml-launcher --opengl --fullscreen --skip-app-switcher --app meego-app-photos");
                } else {
                    processLauncher.launch ("meego-qml-launcher --opengl --fullscreen --skip-app-switcher --app meego-app-video");
                }
            }
        }
    }

    Image {
        id: topBarShadow
        width: parent.width
        source: "image://theme/toolbar-shadow"
    }
}

Make the photo review bin follow the camera state correctly

/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7

Column {
    width: parent.width
    height: topBarBackground.height + topBarShadow.height

    Image {
        id: topBarBackground

        width: parent.width

        source: {
            if (orientation == 1 || orientation == 3) {
                return "image://theme/titlebar_l";
            } else {
                return "image://theme/titleBar_p";
            }
        }

        ToggleSwitch {
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
            state: camera.state
            onToggled: {
                camera.state = state;
            }
        }

        PhotoReviewBin {
            id: reviewBin
            x: parent.width - width
            anchors.verticalCenter: parent.verticalCenter
            source: camera.imageLocation
            type: camera.state

            onClicked: {
                if (reviewBin.type == "photo") {
                    processLauncher.launch ("meego-qml-launcher --opengl --fullscreen --skip-app-switcher --app meego-app-photos");
                } else {
                    processLauncher.launch ("meego-qml-launcher --opengl --fullscreen --skip-app-switcher --app meego-app-video");
                }
            }
        }
    }

    Image {
        id: topBarShadow
        width: parent.width
        source: "image://theme/toolbar-shadow"
    }
}


/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7
import MeeGo.Components 0.1
import MeeGo.App.IM 0.1
import TelepathyQML 0.1

Item {
    width: parent.width
    height: setupDelegate.detailsHeight

    ExpandingBox {
        id: setupDelegate

        detailsComponent: accountFactory.embeddedAccountContent(model.id, setupDelegate)

        property int itemWidth: parent.width
        property int accountStatus: model.statusType
        property variant accountContent: detailsItem.accountContent
        //property bool expanded: false
        property int detailsHeight: childrenRect.height

        //expandedHeight: detailsItem.height + expandButton.height

        height:  (serviceIcon != ""? serviceIcon.height : accountTypeName.height)

        Image {
            id: serviceIcon
            anchors.top: parent.top
            anchors.left: parent.left
            anchors.leftMargin: 10
            source: accountFactory.accountIcon(model.icon, model.connectionStatus)
            smooth: true
        }

        Text {
            id: accountTypeName
            anchors.left: serviceIcon.right
            anchors.verticalCenter: parent.verticalCenter
            anchors.margins: 10
            text: model.displayName
            elide: Text.ElideRight
            font.weight: Font.Bold
            color: theme_fontColorNormal
        }
    }
}

Remove bold text from the Account settings

/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7
import MeeGo.Components 0.1
import MeeGo.App.IM 0.1
import TelepathyQML 0.1

Item {
    width: parent.width
    height: setupDelegate.detailsHeight

    ExpandingBox {
        id: setupDelegate

        detailsComponent: accountFactory.embeddedAccountContent(model.id, setupDelegate)

        property int itemWidth: parent.width
        property int accountStatus: model.statusType
        property variant accountContent: detailsItem.accountContent
        //property bool expanded: false
        property int detailsHeight: childrenRect.height

        //expandedHeight: detailsItem.height + expandButton.height

        height:  (serviceIcon != ""? serviceIcon.height : accountTypeName.height)

        Image {
            id: serviceIcon
            anchors.top: parent.top
            anchors.left: parent.left
            anchors.leftMargin: 10
            source: accountFactory.accountIcon(model.icon, model.connectionStatus)
            smooth: true
        }

        Text {
            id: accountTypeName
            anchors.left: serviceIcon.right
            anchors.verticalCenter: parent.verticalCenter
            anchors.margins: 10
            text: model.displayName
            elide: Text.ElideRight
            color: theme_fontColorNormal
        }
    }
}


import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1

import UM 1.0 as UM

UM.Dialog {
    id: base

    //: Add Printer dialog title
    title: qsTr("About Cura");

    Label {
        text: "Cura";
    }

    rightButtons: Button {
        text: "Close";

        onClicked: base.visible = false;
    }
}


import QtTest 1.0
import QtQuick 2.0

import org.jemc.qml.Sockets 1.0

TestCase {
    id: test
    name: "UDPMulticastSocket"

    UDPMulticastSocket {
        id: socket
        group: "239.255.250.250"
        port: 9131

        property var verified: false
        property var response: ""
        property var expected: /HTTP\/[^\n]* OK/

        onRead: response += message
    }

    function wait_for_connect()    { while(socket.state!=4) { wait(0) } }
    function wait_for_disconnect() { while(socket.state!=0) { wait(0) } }

    function test_it() {
        socket.connect()
        wait_for_connect()

        compare(socket.response, "")
        socket.write("test")
        wait(100)
        compare(socket.response, "test")

        socket.disconnect()
        wait_for_disconnect()
    }
}


import qbs

QtApplication {
    name: "qbs_fuzzy-test"
    destinationDirectory: "bin"
    type: "application"
    consoleApplication: true
    files: [
        "commandlineparser.cpp",
        "commandlineparser.h",
        "fuzzytester.cpp",
        "fuzzytester.h",
        "main.cpp",
    ]
}

Fix self hosted build with Qt 5.7, where C++11 is now required

import qbs

QtApplication {
    name: "qbs_fuzzy-test"
    destinationDirectory: "bin"
    type: "application"
    consoleApplication: true
    cpp.cxxLanguageVersion: "c++11"
    files: [
        "commandlineparser.cpp",
        "commandlineparser.h",
        "fuzzytester.cpp",
        "fuzzytester.h",
        "main.cpp",
    ]
}


Project {
	minimumQbsVersion: "1.10"

	references: [
		"cutehmi_1",
		"cutehmi_app_1",
		"cutehmi_authssh_1",
		"cutehmi_charts_1",
		"cutehmi_modbus_1",
		"cutehmi_services_1",
		"cutehmi_stupid_1",
		"cutehmi_xml_1",
		"templates_minimal_1"
	]
}

Add 'templates_projectplugin_1' to the list.

Project {
	minimumQbsVersion: "1.10"

	references: [
		"cutehmi_1",
		"cutehmi_app_1",
		"cutehmi_authssh_1",
		"cutehmi_charts_1",
		"cutehmi_modbus_1",
		"cutehmi_services_1",
		"cutehmi_stupid_1",
		"cutehmi_xml_1",
		"templates_minimal_1",
		"templates_projectplugin_1"
	]
}


// Run with `qmlscene -I ../.. app.qml`

import QtQuick 2.0
import HttpServer 1.0

Item {
    width: 300; height: 200

    HttpServer {
        id: server
        Component.onCompleted: listen("127.0.0.1", 5000)

        onNewRequest: { // request, response
            response.writeHead(200)
            response.write("
Request properties

")
            response.write("
remoteAddress: " + request.remoteAddress + "
")
            response.write("
remotePort: " + request.remotePort + "
")
            response.write("
method: " + request.method + "
")
            response.write("
url: " + request.url + "
")
            response.write("
path: " + request.path + "
")
            response.write("
httpVersion: " + request.httpVersion + "
")
            response.end()
        }
    }

    Text {
        anchors.centerIn: parent
        text: "Serving at localhost:5000"
        onLinkActivated: Qt.openUrlExternally(link)
    }
}


// -*- qml -*-
import QtQuick 1.1
import com.nokia.meego 1.1
import QtCamera 1.0

Slider {
        id: slider
        property alias camera: zoom.camera
        platformStyle: SliderStyle {
                // HACK
                handleBackground: " "
                handleBackgroundPressed: " "
        }

        Zoom {
                id: zoom
                value: slider.value
        }

        orientation: Qt.Horizontal
        width: 500
        height: 50
        stepSize:0.1
        minimumValue: zoom.minimum
        maximumValue: zoom.maximum

        state: "hidden"
        states: [
        State {
                name: "visible"
                when: slider.pressed
                PropertyChanges { target: slider; opacity: 1.0 }
        },
        State {
                name: "hidden"
                when: !slider.pressed
                PropertyChanges { target: slider; opacity: 0.2 }
        }]

        transitions: Transition {
                to: "hidden"
                SequentialAnimation {
                        PauseAnimation { duration: 2000 }
                        NumberAnimation { target: slider; property: "opacity"; duration: 250 }
                }
        }
}

Reset zoom value when camera mode is changed

// -*- qml -*-
import QtQuick 1.1
import com.nokia.meego 1.1
import QtCamera 1.0

Slider {
        id: slider
        property alias camera: zoom.camera
        platformStyle: SliderStyle {
                // HACK
                handleBackground: " "
                handleBackgroundPressed: " "
        }

        Zoom {
                id: zoom
                value: slider.value
        }

        Connections {
                target: camera
                onModeChanged: slider.value = zoom.minimum;
        }

        orientation: Qt.Horizontal
        width: 500
        height: 50
        stepSize:0.1
        minimumValue: zoom.minimum
        maximumValue: zoom.maximum

        state: "hidden"
        states: [
        State {
                name: "visible"
                when: slider.pressed
                PropertyChanges { target: slider; opacity: 1.0 }
        },
        State {
                name: "hidden"
                when: !slider.pressed
                PropertyChanges { target: slider; opacity: 0.2 }
        }]

        transitions: Transition {
                to: "hidden"
                SequentialAnimation {
                        PauseAnimation { duration: 2000 }
                        NumberAnimation { target: slider; property: "opacity"; duration: 250 }
                }
        }
}


Rectangle {
	id: roundButtonProto;
	signal toggled;
	property string icon;
	property bool containsMouse: roundButtonInnerArea.containsMouse;
	width: 76;
	height: width;
	radius: width / 2;
	color: colorTheme.backgroundColor;

	Image {
		anchors.centerIn: parent;
		source: parent.icon;
	}

	MouseArea {
		id: roundButtonInnerArea;
		anchors.fill: parent;
		hoverEnabled: true;

		onClicked: { roundButtonProto.toggled(); }
	}
}

Fix channel control icon sizes.

Rectangle {
	id: roundButtonProto;
	signal toggled;
	property string icon;
	property bool containsMouse: roundButtonInnerArea.containsMouse;
	width: 76;
	height: width;
	radius: width / 2;
	color: colorTheme.backgroundColor;

	Image {
		anchors.fill: parent;
		anchors.margins: parent.width / 4;
		fillMode: Image.PreserveAspectFit;
		source: parent.icon;
	}

	MouseArea {
		id: roundButtonInnerArea;
		anchors.fill: parent;
		hoverEnabled: true;

		onClicked: { roundButtonProto.toggled(); }
	}
}


Add a QML item that performs recolouring of the image it loads using a shader

import QtQuick 2.1

Item {
    id: base;

    property alias source: img.source;
    property alias color: shader.color;

    Image {
        id: img;
        anchors.fill: parent;
        visible: false;
    }

    ShaderEffect {
        id: shader;
        anchors.fill: parent;

        property variant src: img;
        property color color: '#fff';

        vertexShader: "
            uniform highp mat4 qt_Matrix;
            attribute highp vec4 qt_Vertex;
            attribute highp vec2 qt_MultiTexCoord0;
            varying highp vec2 coord;
            void main() {
                coord = qt_MultiTexCoord0;
                gl_Position = qt_Matrix * qt_Vertex;
            }"

        fragmentShader: "
            varying highp vec2 coord;
            uniform sampler2D src;
            uniform lowp vec4 color;
            uniform lowp float qt_Opacity;
            void main() {
                lowp vec4 tex = texture2D(src, coord);
                lowp float alpha = tex.a  * qt_Opacity;
                gl_FragColor = vec4(color.r * alpha, color.g * alpha, color.b * alpha, alpha);
            }"
    }
}


/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7
import MeeGo.Components 0.1
import MeeGo.App.Clocks 0.1

Window {
    id: window

    // simplify orientation code
    property bool isLandscape: orientation == 1 || orientation == 3
    property bool isPortrait: orientation == 0 || orientation == 2

    showToolBarSearch: false

    bookMenuModel: [qsTr("Clocks"), qsTr("Alarms")]
    bookMenuPayload: [ clocksPage, alarmsPage ]
    Component { id: clocksPage; ClocksPage {} }
    Component { id: alarmsPage; AlarmsPage {} }

    property string indexValueName: "window.bookMenuSelectedIndex"  // i18n ok

    SaveRestoreState {
        id: windowState
        onSaveRequired: {
            // Save the book page we're on.
            setValue(indexValueName, window.bookMenuSelectedIndex)
            sync()
        }
    }

    Component.onCompleted: {
        // Load the page we were previously on if necessary.  Otherwise, load the clocks
        // page by default.

        var i = (windowState.restoreRequired ? windowState.value(indexValueName, 0) : 0)

        switchBook(bookMenuPayload[i])
    }

    onBookMenuSelectedIndexChanged: windowState.invalidate()
}

Use Window.in* boolean properties to detect landscape changes.

/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Qt 4.7
import MeeGo.Components 0.1
import MeeGo.App.Clocks 0.1

Window {
    id: window

    // simplify orientation code
    property bool isLandscape: window.inLandscape || window.inInvertedLandscape
    property bool isPortrait: window.inPortrait || window.inInvertedPortrait

    showToolBarSearch: false

    bookMenuModel: [qsTr("Clocks"), qsTr("Alarms")]
    bookMenuPayload: [ clocksPage, alarmsPage ]
    Component { id: clocksPage; ClocksPage {} }
    Component { id: alarmsPage; AlarmsPage {} }

    property string indexValueName: "window.bookMenuSelectedIndex"  // i18n ok

    SaveRestoreState {
        id: windowState
        onSaveRequired: {
            // Save the book page we're on.
            setValue(indexValueName, window.bookMenuSelectedIndex)
            sync()
        }
    }

    Component.onCompleted: {
        // Load the page we were previously on if necessary.  Otherwise, load the clocks
        // page by default.

        var i = (windowState.restoreRequired ? windowState.value(indexValueName, 0) : 0)

        switchBook(bookMenuPayload[i])
    }

    onBookMenuSelectedIndexChanged: windowState.invalidate()
}


import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2

ColumnLayout {
    id: header
    spacing: 0
    height: 48
    Layout.maximumHeight: 48
    Layout.alignment: Qt.AlignLeft | Qt.AlignTop
    Rectangle {
        id: background
        Layout.minimumHeight: 45
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#ffffff"
        Image {
            id: logo
            width: 100
            height: 28
            fillMode: Image.PreserveAspectCrop
            anchors.left: parent.left
            anchors.leftMargin: 12
            anchors.bottomMargin: 5
            anchors.bottom: parent.bottom
            source: "../images/yubico-logo.svg"
        }
    }
    Rectangle {
        id: headerBorder
        Layout.minimumHeight: 3
        Layout.maximumHeight: 3
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#9aca3c"
    }
}

Add help link in header

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2

ColumnLayout {
    id: header
    spacing: 0
    height: 48
    Layout.maximumHeight: 48
    Layout.alignment: Qt.AlignLeft | Qt.AlignTop
    Rectangle {
        id: background
        Layout.minimumHeight: 45
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#ffffff"
        Image {
            id: logo
            width: 100
            height: 28
            fillMode: Image.PreserveAspectCrop
            anchors.left: parent.left
            anchors.leftMargin: 12
            anchors.bottomMargin: 5
            anchors.bottom: parent.bottom
            source: "../images/yubico-logo.svg"
        }
        Label {
            text: qsTr("help")
            textFormat: Text.RichText
            anchors.right: parent.right
            anchors.rightMargin: 12
            anchors.bottomMargin: 5
            anchors.bottom: parent.bottom
            onLinkActivated: Qt.openUrlExternally(link)
            MouseArea {
                anchors.fill: parent
                acceptedButtons: Qt.NoButton
                cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
            }
        }
    }
    Rectangle {
        id: headerBorder
        Layout.minimumHeight: 3
        Layout.maximumHeight: 3
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "#9aca3c"
    }
}


import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1

import UM 1.0 as UM

Rectangle {
    id: base;

    property Action addMachineAction;
    property Action configureMachinesAction;

    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.AllButtons;

        onWheel: {
            wheel.accepted = true;
        }
    }

    ColumnLayout {
        anchors.fill: parent;
        anchors.topMargin: UM.Theme.sizes.default_margin.height;
        anchors.bottomMargin: UM.Theme.sizes.default_margin.height;

        spacing: UM.Theme.sizes.default_margin.height;

        SidebarHeader {
            id: header;

            Layout.fillWidth: true;

            addMachineAction: base.addMachineAction;
            configureMachinesAction: base.configureMachinesAction;
        }

        Loader {
            id: sidebarContents;

            Layout.fillWidth: true;
            Layout.fillHeight: true;

            source: header.currentModeFile;
        }

        OutputGCodeButton {
            Layout.preferredWidth: base.width - UM.Theme.sizes.default_margin.width * 2;
            Layout.preferredHeight: UM.Theme.sizes.section.height;
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter;
        }
    }
}

Use AngledCornerRectangle for the sidebar background

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1

import UM 1.0 as UM

UM.AngledCornerRectangle {
    id: base;

    property Action addMachineAction;
    property Action configureMachinesAction;

    cornerSize: UM.Theme.sizes.default_margin.width;

    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.AllButtons;

        onWheel: {
            wheel.accepted = true;
        }
    }

    ColumnLayout {
        anchors.fill: parent;
        anchors.topMargin: UM.Theme.sizes.default_margin.height;
        anchors.bottomMargin: UM.Theme.sizes.default_margin.height;

        spacing: UM.Theme.sizes.default_margin.height;

        SidebarHeader {
            id: header;

            Layout.fillWidth: true;

            addMachineAction: base.addMachineAction;
            configureMachinesAction: base.configureMachinesAction;
        }

        Loader {
            id: sidebarContents;

            Layout.fillWidth: true;
            Layout.fillHeight: true;

            source: header.currentModeFile;
        }

        OutputGCodeButton {
            Layout.preferredWidth: base.width - UM.Theme.sizes.default_margin.width * 2;
            Layout.preferredHeight: UM.Theme.sizes.button.height;
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter;
        }
    }
}


import QtQuick.Controls 1.0
//
ComboBox{
    id : cBox

    // selected item, only assigned if user
    // clicks on an item in the context menu,
    // not if changing the current item index
    property variant item
    // changes active item
    // without triggering the
    // the on current item changed signal
    property int currentItem

    property bool _skipNext : false

    onModelChanged : {
        console.log("model assigned")
        _skipNext = true
    }

    onCurrentItemChanged : {
        // skip next onCurrentIndexChanged
        _skipNext = true
        currentIndex = currentItem
    }

    onCurrentIndexChanged: {
        // currentIndex is changed if a new model
        // is assigned, so we need to ignore the signal
        // once every time a new model is assigned
        if (_skipNext) {
            _skipNext = false
        } else {
            // assign selected item to the item
            // property, so that the onItemChanged
            // signal is triggered
            cBox.item = cBox.model.get(currentIndex)
        }
    }
}

Add a built-in label to the Controls combobox

import QtQuick 2.0
import QtQuick.Controls 1.0

Row {
    property alias label : comboLabel.text
    property alias model : cBox.model
    property alias item : cBox.item
    property alias currentItem : cBox.currentItem
    property alias currentIndex : cBox.currentIndex

    // no spacing if the label is empty, so that the combobox
    // can be used as a standalone label-less combobox
    spacing : comboLabel.text ? rWin.c.style.main.spacing : 0
    Label {
        id : comboLabel
    }

    ComboBox{
        id : cBox
        anchors.verticalCenter : comboLabel.verticalCenter
        // selected item, only assigned if user
        // clicks on an item in the context menu,
        // not if changing the current item index
        property variant item
        // changes active item
        // without triggering the
        // the on current item changed signal
        property int currentItem

        property bool _skipNext : false

        onModelChanged : {
            console.log("model assigned")
            _skipNext = true
        }

        onCurrentItemChanged : {
            // skip next onCurrentIndexChanged
            _skipNext = true
            currentIndex = currentItem
        }

        onCurrentIndexChanged: {
            // currentIndex is changed if a new model
            // is assigned, so we need to ignore the signal
            // once every time a new model is assigned
            if (_skipNext) {
                _skipNext = false
            } else {
                // assign selected item to the item
                // property, so that the onItemChanged
                // signal is triggered
                cBox.item = cBox.model.get(currentIndex)
            }
        }
    }
}


// Copyright (c) 2015 Piotr Tworek. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.YTPlayer file.

import QtQuick 2.0
import Sailfish.Silica 1.0

Image {
    fillMode: Image.PreserveAspectCrop

    property alias indicatorSize: indicator.size

    BusyIndicator {
        id: indicator
        size: BusyIndicatorSize.Small
        anchors.centerIn: parent
        running: parent.status === Image.Loading
    }

    Rectangle {
        anchors.fill: parent
        color: Theme.secondaryHighlightColor
        visible: status === Image.Error
        Label {
            anchors.centerIn: parent
            font.pixelSize: Theme.fontSizeExtraSmall
            //: Label shown where video thumbnail is not valid, can't be loaded.
            //: Should be very short 8-10 characters max.
            //% "No image"
            text: qsTrId("ytplayer-label-broken-image")
            color: Theme.primaryColor
        }
    }
}

Add maximum width to no-image placeholder.

// Copyright (c) 2015 Piotr Tworek. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.YTPlayer file.

import QtQuick 2.0
import Sailfish.Silica 1.0

Image {
    fillMode: Image.PreserveAspectCrop

    property alias indicatorSize: indicator.size

    BusyIndicator {
        id: indicator
        size: BusyIndicatorSize.Small
        anchors.centerIn: parent
        running: parent.status === Image.Loading
    }

    Rectangle {
        anchors.fill: parent
        color: Theme.secondaryHighlightColor
        visible: status === Image.Error
        Label {
            anchors.centerIn: parent
            width: parent.width
            maximumLineCount: 1
            font.pixelSize: Theme.fontSizeExtraSmall
            horizontalAlignment: Text.AlignHCenter
            //: Label shown where video thumbnail is not valid, can't be loaded.
            //: Should be very short 8-10 characters max.
            //% "No image"
            text: qsTrId("ytplayer-label-broken-image")
            color: Theme.primaryColor
        }
    }
}


import VPlay 1.0
import QtQuick 1.1

import "manager"

GameWindow {
  id: window
  width: 320
  height: 480

  minimizeable: true

  // this would disable the fps label both for QML & cocos renderer - if only qml renderer should be disabled use fpsTextItem.visible: false
  displayFpsEnabled: developerBuild

  // in the developer version, the fps are displayed
  property bool developerBuild: !system.publishBuild

  // forward events always to the controller of the loaded active scene
  Keys.forwardTo: activeScene.controllerOfScene

  // sceneLoader and managers should be available in every scene
  property alias window: window
  property alias audioManager: audioManager
  property alias settingsManager: settingsManager
  property alias sceneLoader: sceneLoader
  property alias fontHUD: fontHUD

  // Custom font loading of ttf fonts
  FontLoader {
    id: fontHUD
    source: "fonts/propaganda.ttf"
  }

  // all content is loaded dynamically by the sceneLoader element.
  SceneLoader {
    id: sceneLoader
  }

  // global music and sound management
  AudioManager {
    id: audioManager
  }

  // settings can be stored directly by the settings manager
  SettingsManager {
    id: settingsManager
  }

  EntityManager {
    id: entityManager
    // forward container allways to container of scene
    entityContainer: activeScene.entityContainerOfScene
    // forward dynamic entity list e.g. used for level editor
    //dynamicCreationEntityList: activeScene.dynamicCreationEntityList
  }
}

Add maximizeable flag to support maximizeable app.

import VPlay 1.0
import QtQuick 1.1

import "manager"

GameWindow {
  id: window
  width: 320
  height: 480

  minimizeable: true
  maximizeable:  true

  // this would disable the fps label both for QML & cocos renderer - if only qml renderer should be disabled use fpsTextItem.visible: false
  displayFpsEnabled: developerBuild

  // in the developer version, the fps are displayed
  property bool developerBuild: !system.publishBuild

  // forward events always to the controller of the loaded active scene
  Keys.forwardTo: activeScene.controllerOfScene

  // sceneLoader and managers should be available in every scene
  property alias window: window
  property alias audioManager: audioManager
  property alias settingsManager: settingsManager
  property alias sceneLoader: sceneLoader
  property alias fontHUD: fontHUD

  // Custom font loading of ttf fonts
  FontLoader {
    id: fontHUD
    source: "fonts/propaganda.ttf"
  }

  // all content is loaded dynamically by the sceneLoader element.
  SceneLoader {
    id: sceneLoader
  }

  // global music and sound management
  AudioManager {
    id: audioManager
  }

  // settings can be stored directly by the settings manager
  SettingsManager {
    id: settingsManager
  }

  EntityManager {
    id: entityManager
    // forward container allways to container of scene
    entityContainer: activeScene.entityContainerOfScene
    // forward dynamic entity list e.g. used for level editor
    //dynamicCreationEntityList: activeScene.dynamicCreationEntityList
  }
}


import QtQuick 2.0
import QtQuick.Window 2.2
import QtQuick.Controls 1.1

Window {
    id: window
    title: "Lit"

    function init() {
        window.flags |= Qt.WindowStaysOnTopHint
        window.width = 400
        window.height = 300
        window.show()
    }

    onClosing: Qt.quit()

    TextEdit {
        id: editor
        anchors.fill: parent
        wrapMode: Text.Wrap

        color: "#222"
        selectionColor: "#4fc3f7"
        selectedTextColor: "#333"

        font.pixelSize: 24
        font.family: "Noto Sans T Chinese"
        font.weight: Font.DemiBold
        renderType: TextEdit.NativeRendering
        smooth: true

        focus: true
        selectByMouse: true

        onTextChanged: {
            app.text = format(text)
        }

        function format(text) {
            return text
                .replace(/[<>&\n]/g, function(c) {
                    switch (c) {
                        case "&": return "&"
                        case "<": return "<"
                        case ">": return ">"
                        case "\n": return "
"
                    }})
                .replace(/`(.+)`/g, "$1")
                .replace(/\*\*(.+)\*\*/g, "$1")
                .replace(/~~(.+)~~/g, "<s>$1</s>")
        }
    }
}

Add italics and fix inline style spanning across lines

import QtQuick 2.0
import QtQuick.Window 2.2
import QtQuick.Controls 1.1

Window {
    id: window
    title: "Lit"

    function init() {
        window.flags |= Qt.WindowStaysOnTopHint
        window.width = 400
        window.height = 300
        window.show()
    }

    onClosing: Qt.quit()

    TextEdit {
        id: editor
        anchors.fill: parent
        wrapMode: Text.Wrap

        color: "#222"
        selectionColor: "#4fc3f7"
        selectedTextColor: "#333"

        font.pixelSize: 24
        font.family: "Noto Sans T Chinese"
        font.weight: Font.DemiBold
        renderType: TextEdit.NativeRendering
        smooth: true

        focus: true
        selectByMouse: true

        onTextChanged: {
            app.text = format(text)
        }

        function format(text) {
            return text
                .replace(/[<>&\n]/g, function(c) {
                    switch (c) {
                        case "&": return "&"
                        case "<": return "<"
                        case ">": return ">"
                        case "\n": return "
"
                    }})
                .replace(/`(.+)`/g, "$1")
                .replace(/\*\*([^\n\*]+)\*\*/g, "$1")
                .replace(/\*([^\s\n\*]+)\*/g, "*$1*")
                .replace(/~~(.+)~~/g, "<s>$1</s>")
        }
    }
}


import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

Control {
    id: root

    implicitHeight: programName.implicitHeight
    implicitWidth: programName.implicitWidth + selectButton.implicitWidth + deleteButton.implicitWidth + row.spacing

    Rectangle {
        anchors.fill: root
        color: "orange"
    }

    RowLayout {
        id: row

        anchors.fill: root

        TextField {
            id: programName

            Layout.fillWidth: true

            readOnly: model.programId === 0

            text: model.name
            Binding {
                target: model
                property: "name"
                value: programName.text
            }
        }
        Button {
            id: selectButton
            text: "Select"
            onClicked: {
                app.activeProgramId = programId;
            }
        }
        Button {
            id: deleteButton
            enabled: model.programId > 0
            text: "Delete"
            onClicked: {
                app.deleteProgram(model.programId);
            }
        }
    }

    Rectangle {
        anchors.fill: root
        color: "transparent"
        border.color: "red"
        border.width: 1
    }
}

Set program channel from the UI

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

Control {
    id: root

    implicitHeight: programName.implicitHeight
    implicitWidth: programName.implicitWidth + selectButton.implicitWidth + deleteButton.implicitWidth + row.spacing

    Rectangle {
        anchors.fill: root
        color: "orange"
    }

    RowLayout {
        id: row

        anchors.fill: root

        TextField {
            id: programName

            Layout.fillWidth: true

            readOnly: model.programId === 0

            text: model.name
            Binding {
                target: model
                property: "name"
                value: programName.text
            }
        }
        Text {
            Layout.fillWidth: false;
            text: "Channel"
        }
        SpinBox {
            id: channelSpinbox
            editable: true
            from: 1
            to: 16
            value: channel
            Binding {
                target: model
                property: "channel"
                value: channelSpinbox.value
            }
        }
        Button {
            id: selectButton
            text: "Select"
            onClicked: {
                app.activeProgramId = programId;
            }
        }
        Button {
            id: deleteButton
            enabled: model.programId > 0
            text: "Delete"
            onClicked: {
                app.deleteProgram(model.programId);
            }
        }
    }

    Rectangle {
        anchors.fill: root
        color: "transparent"
        border.color: "red"
        border.width: 1
    }
}


Item {
	property Font font: Font {}
	property Color color: "#000";
	property string value;
	width: 100;
	height: 40;

	constructor: {
		this.element.on("change", function() { this.value = this.element.dom.value }.bind(this))
	}

	/// @private
	function _update(name, value) {
		switch (name) {
			case 'width':
			case 'height': this._updateSize(); break
		}

		_globals.core.Item.prototype._update.apply(this, arguments);
	}

	/// @private
	function getTag() { return 'select' }

	/// @private
	function _updateSize() {
		var style = { width: this.width, height: this.height }
		this.style(style)
	}

	/// add option into select
	append(text): {
		var option = this._context.createElement('option')
		option.dom.value = text
		option.dom.innerHTML = text
		this.element.append(option)
	}
}

Add 'value' and 'currentIndex' property.

Item {
	property Font font: Font {}
	property Color color: "#000";
	property int currentIndex;
	property string value;
	property string text;
	width: 100;
	height: 40;

	constructor: {
		this.element.on("change", function() {
			this.value = this.element.dom.value
			var idx = this.element.dom.selectedIndex
			this.currentIndex = idx
			this.text = this.element.dom[idx].label
		}.bind(this))
	}

	/// @private
	function _update(name, value) {
		switch (name) {
			case 'width':
			case 'height': this._updateSize(); break
		}

		_globals.core.Item.prototype._update.apply(this, arguments);
	}

	/// @private
	function getTag() { return 'select' }

	/// @private
	function _updateSize() {
		var style = { width: this.width, height: this.height }
		this.style(style)
	}

	/// add option into select
	append(value, text): {
		var option = this._context.createElement('option')
		option.dom.value = value
		option.dom.innerHTML = text
		this.element.append(option)
	}
}


import QtQuick 2.12
import QtQuick.Controls 2.5

import ".."

Item {
    id: root

    signal changed(string value)

    property string name
    property var options
    property var values: options
    property Setting setting
    property string currentValue: setting.value

    implicitHeight: item.implicitHeight

    SettingItem {
        id: item

        name: root.name
        subtitle: options[values.indexOf(setting.value)] || ""
        anchors.fill: parent

        onClicked: dialog.open()

        Dialog {
            id: dialog

            title: root.name
            anchors.centerIn: Overlay.overlay
            modal: true
            standardButtons: Dialog.Ok | Dialog.Cancel

            onAccepted: {
                var val = currentValue
                setting.setValue(val)
                root.changed(val)
            }
            onRejected: currentValue = setting.value

            height: root.options.length * 30 + 130 // TODO: do this properly

            ButtonGroup {
                id: buttonGroup
            }

            ListView {
                anchors.fill: parent
                model: root.options
                height: root.options.length * 30

                delegate: RadioDelegate {
                    width: parent.width
                    checked: values[index] === currentValue
                    text: modelData
                    ButtonGroup.group: buttonGroup
                    height: 30 // from 40
                    padding: 8 // from 12

                    indicator: MiniRadioIndicator {
                        control: parent
                        size: 18 // from 28
                    }

                    onCheckedChanged: if (checked) currentValue = values[index]
                }
            }
        }
    }
}

Fix combo settings using non-string values

import QtQuick 2.12
import QtQuick.Controls 2.5

import ".."

Item {
    id: root

    signal changed(string value)

    property string name
    property var options
    property var values: options
    property Setting setting
    property var currentValue: setting.value

    implicitHeight: item.implicitHeight

    SettingItem {
        id: item

        name: root.name
        subtitle: options[values.indexOf(setting.value)] || ""
        anchors.fill: parent

        onClicked: dialog.open()

        Dialog {
            id: dialog

            title: root.name
            anchors.centerIn: Overlay.overlay
            modal: true
            standardButtons: Dialog.Ok | Dialog.Cancel

            onAccepted: {
                var val = currentValue
                setting.setValue(val)
                root.changed(val)
            }
            onRejected: currentValue = setting.value

            height: root.options.length * 30 + 130 // TODO: do this properly

            ButtonGroup {
                id: buttonGroup
            }

            ListView {
                anchors.fill: parent
                model: root.options
                height: root.options.length * 30

                delegate: RadioDelegate {
                    width: parent.width
                    checked: values[index] === currentValue
                    text: modelData
                    ButtonGroup.group: buttonGroup
                    height: 30 // from 40
                    padding: 8 // from 12

                    indicator: MiniRadioIndicator {
                        control: parent
                        size: 18 // from 28
                    }

                    onCheckedChanged: if (checked) currentValue = values[index]
                }
            }
        }
    }
}


import qbs

Stm32Product {
    type: "application" // To suppress bundle generation on Mac
    consoleApplication: true

    cpp.positionIndependentCode: false
    cpp.executableSuffix: ".elf"
    cpp.linkerFlags: {
        base.push("-Xlinker");
        base.push("--gc-sections");
        return base;
    }
}

Remove executable suffix. It does not works!

import qbs

Stm32Product {
    type: "application" // To suppress bundle generation on Mac
    consoleApplication: true

    cpp.positionIndependentCode: false
    cpp.linkerFlags: {
        base.push("-Xlinker");
        base.push("--gc-sections");
        return base;
    }
}