import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow { id: main
        Item { id: env

        }
        property string sourceFileName: "MainUI.qml"
        property string menuFileName: "MainMenu.qml"
        property string toolBarFileName: "MainToolBar.qml"

        visible: true

        menuBar: mainMenuLoader.item
        toolBar: toolBarLoader.item

        Connections {
                target: quiver
                onPendingConnectionRequestChanged: {
                        mainLoader.source = ""
                        mainLoader.source = sourceFileName
                }
        }

        Loader { id: mainLoader
                source: sourceFileName
                anchors.fill: parent
                focus: true
        }

        Loader { id: mainMenuLoader
                source: menuFileName
        }

        Loader { id: toolBarLoader
                source: toolBarFileName
        }
}

Add in windowblur QML to test.

import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4

import BSComponents 1.0

ApplicationWindow { id: main
    color: "transparent"

        Item { id: env

        }
        property string sourceFileName: "MainUI.qml"
        property string menuFileName: "MainMenu.qml"
        property string toolBarFileName: "MainToolBar.qml"

        property alias backgroundColor: blur.backgroundColor

        visible: true

        menuBar: mainMenuLoader.item
        toolBar: toolBarLoader.item

        Connections {
                target: quiver
                onPendingConnectionRequestChanged: {
                        mainLoader.source = ""
                        mainLoader.source = sourceFileName
                }
        }

        Loader { id: mainLoader
                source: sourceFileName
                anchors.fill: parent
                focus: true
        }

        Loader { id: mainMenuLoader
                source: menuFileName
        }

        Loader { id: toolBarLoader
                source: toolBarFileName
        }

        WindowBackgroundBlur {
            id: blur
            window: root
            radius: 25
            backgroundColor: "#a0f7fafc"
        }
}


import QtQuick 2.0
import FluidUi 1.0

Item {
	width: 300
	height: 300

	Column {
		id: column
		spacing: 30
		width: 100

		Button { id: disabledButton; text: "Disabled"; enabled: false }
		Button { id: enabledButton; text: "Enabled" }
Row {
                Label { text: sl1.value.toFixed(2) ; color: "green"; width: 80 }
                Label { visible: screen.currentOrientation == Screen.Landscape; width: root.textColumnWidth; wrapMode: Text.Wrap; text: "Default Slider" }
                Slider { id: sl1 ; width:sliderWidth}
            }

Switch {
                    id: switch2
                    checked: true
                }
                Switch {
                    id: switch1
                    checked: false
                }

	}
}

Add a label and remove switches.

import QtQuick 2.0
import FluidCore 1.0

Item {
	width: 300
	height: 300

	Column {
		id: column
		spacing: 30
		width: 100

		FluidCore.Label { text: "CIAO" }
		FluidCore.Button { id: disabledButton; text: "Disabled"; enabled: false }
		FluidCore.Button { id: enabledButton; text: "Enabled" }
	}
}


Rectangle {
	signal clicked;
	property bool clickable: true;
	property bool hoverable: true;
	color: "transparent";

	property bool hover;
	property string cursor;

	onCursorChanged: {
		this.element.css('cursor', value);
	}

	onClickableChanged: {
		if (value){
			this.element.click(this.clicked.bind(this))
		}
		else {
			this.element.unbind('click')
		}
	}

	onHoverableChanged: {
		var self = this
		if (value){
			this.element.hover(function() { self.hover = true }, function() { self.hover = false })
		}
		else {
			this.element.unbind('mouseenter mouseleave')
		}
	}

	onCompleted: {
		var self = this
		if (this.clickable)
			this.element.click(this.clicked.bind(this))
		if (this.hoverable)
			this.element.hover(function() { self.hover = true }, function() { self.hover = false })
	}
}

Set 'pointer' cursor as default for webItem + fix format.

Rectangle {
	signal clicked;
	property bool hover;
	property bool clickable: true;
	property bool hoverable: true;
	property string cursor;
	color: "transparent";

	onCursorChanged: { this.element.css('cursor', value) }

	onClickableChanged: {
		if (value)
			this.element.click(this.clicked.bind(this))
		else
			this.element.unbind('click')
	}

	onHoverableChanged: {
		var self = this
		if (value)
			this.element.hover(function() { self.hover = true }, function() { self.hover = false })
		else
			this.element.unbind('mouseenter mouseleave')
	}

	onCompleted: {
		var self = this
		if (this.clickable)
			this.element.click(this.clicked.bind(this))
		if (this.hoverable)
			this.element.hover(function() { self.hover = true }, function() { self.hover = false })

		this.cursor = "pointer"
	}
}


import qbs

Project {
    minimumQbsVersion: "1.7.1"

    CppApplication {
        Depends { name: "Qt.core" }
        Depends { name: "Qt.quick" }

        // Additional import path used to resolve QML modules in Qt Creator's code model
        property pathList qmlImportPaths: []

        cpp.cxxLanguageVersion: "c++11"

        cpp.defines: [
            // The following define makes your compiler emit warnings if you use
            // any feature of Qt which as been marked deprecated (the exact warnings
            // depend on your compiler). Please consult the documentation of the
            // deprecated API in order to know how to port your code away from it.
            "QT_DEPRECATED_WARNINGS",

            // You can also make your code fail to compile if you use deprecated APIs.
            // In order to do so, uncomment the following line.
            // You can also select to disable deprecated APIs only up to a certain version of Qt.
            //"QT_DISABLE_DEPRECATED_BEFORE=0x060000" // disables all the APIs deprecated before Qt 6.0.0
        ]

        files: [
            "plasmoid/metadata.desktop",
            "README.md",
            "plasmoid/**/*.qml",
            "plasmoid/**/*.js",
            "plasmoid/**/*.xml"
        ]

        Group {     // Properties for the produced executable
            fileTagsFilter: product.type
            qbs.install: true
        }
    }
}

Trim down and fix up

import qbs

Project {
    minimumQbsVersion: "1.7.1"
    name: "MCWS Plasmoid"
    Application {

        files: [
            "plasmoid/metadata.desktop",
            "README.md",
            "plasmoid/**/*.qml",
            "plasmoid/**/*.js",
            "plasmoid/**/*.xml"
        ]

        Group {     // Properties for the produced executable
            fileTagsFilter: product.type
            qbs.install: true
        }
    }
}


/*******************************************************************************
** Copyright (c) 2017 Ring.com.
** All Rights Reserved.
**
** This software is a proprietary document of Ring company, and shall not be
** reproduced, distributed or copied for purposes other than the intended use
** without written permission of Ring company.
********************************************************************************
**   Project     :   RING
**   Authors     :   Taras Zaporozhets (taras.zaporozhets@ring.com)
**   Date Created:   2017-03-21
*******************************************************************************/
import qbs
Project {
    CppApplication {
        property string targetDevice: "unicorn"

        name: "QbsProjectExample-" + targetDevice

        consoleApplication: true
        cpp.warningLevel: "all"
        cpp.treatWarningsAsErrors: true
        cpp.cxxLanguageVersion: "c++11"

        files: [
            "src/**",
        ]
        cpp.includePaths: [
            "src/include",
        ]

        cpp.libraryPaths: [

        ]

        cpp.dynamicLibraries: [

        ]

        Group {
            fileTagsFilter: product.type
            qbs.install: true
            qbs.installDir: "/tmp/"
        }
    }
}

Update Qbs file header with MIT license

/*
 * Copyright 2017 Taras Zaporozhets
 *
 * 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 qbs
Project {
    CppApplication {
        property string targetDevice: "unicorn"

        name: "QbsProjectExample-" + targetDevice

        consoleApplication: true
        cpp.warningLevel: "all"
        cpp.treatWarningsAsErrors: true
        cpp.cxxLanguageVersion: "c++11"

        files: [
            "src/**",
        ]
        cpp.includePaths: [
            "src/include",
        ]

        cpp.libraryPaths: [

        ]

        cpp.dynamicLibraries: [

        ]

        Group {
            fileTagsFilter: product.type
            qbs.install: true
            qbs.installDir: "/tmp/"
        }
    }
}


Item {
	property int status;
	property string source;

	property int paintedWidth;
	property int paintedHeight;
	width: paintedWidth;
	height: paintedHeight;

	property int fillMode: Image.Stretch;
}

Revert "Set default width/height values."

Item {
	property int status;
	property string source;

	property int paintedWidth;
	property int paintedHeight;

	property int fillMode: Image.Stretch;
}


import QtQuick 2.12
import QtQuick.Controls 2.5
import Qt.labs.platform 1.1

Item {
    id: root

    property string name
    property alias settingKey: setting.settingKey
    property alias settingDefault: setting.settingDefault

    implicitHeight: item.implicitHeight

    Setting {
        id: setting
    }

    SettingItem {
        id: item

        name: root.name
        subtitle: setting.value
        anchors.fill: parent

        onClicked: dialog.open()

        FolderDialog {
            id: dialog

            acceptLabel: "Select"
            folder: "file:///" + setting.value

            onAccepted: setting.setValue(folder.toString().substring(0, 8) === "file:///" ? folder.toString().substring(8) : folder.toString())
        }
    }
}

Use FileDialog as FolderDialog is not available on Android

import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Dialogs 1.3

Item {
    id: root

    property string name
    property alias settingKey: setting.settingKey
    property alias settingDefault: setting.settingDefault

    implicitHeight: item.implicitHeight

    Setting {
        id: setting
    }

    SettingItem {
        id: item

        name: root.name
        subtitle: setting.value
        anchors.fill: parent

        onClicked: dialog.open()

        FileDialog {
            id: dialog

            // acceptLabel: "Select"
            title: "Please choose a directory"
            folder: "file:///" + setting.value
            // selectExisting: true
            selectFolder: true
            // selectMultiple: false

            onAccepted: setting.setValue(dialog.fileUrl.toString().substring(0, 8) === "file:///" ? dialog.fileUrl.toString().substring(8) : dialog.fileUrl.toString())
        }
    }
}


import Sailfish.Silica 1.0
import QtQuick 2.0

Page {
    id: aboutPage

    SilicaFlickable {
        anchors.fill: parent
        contentWidth: parent.width
        contentHeight: col.height

        VerticalScrollDecorator {}

        Column {
            id: col
            width: parent.width
            spacing: Theme.paddingLarge

            PageHeader {
                title: qsTr("About Sailfactor")
            }

            SectionHeader {
                text: qsTr("License")
            }

            Label {
                anchors {
                    left: parent.left
                    right: parent.right
                    margins: Theme.paddingLarge
                }
                text: qsTr("[to be decided]")
            }

            SectionHeader {
                text: qsTr("Author")
            }

            Label {
                anchors {
                    left: parent.left
                    right: parent.right
                    margins: Theme.paddingLarge
                }
                text: "Lauri Nurmi <lanurmi@iki.fi>"
            }

            SectionHeader {
                text: qsTr("Source code")
            }

            Label {
                anchors {
                    left: parent.left
                    right: parent.right
                    margins: Theme.paddingLarge
                }
                text: qsTr("will be available at github")
                BackgroundItem {
                    anchors.fill: parent
                    onClicked: Qt.openUrlExternally("http://www.github.com/lanurmi/")
                }
            }
        }
    }
}

Fix URL, show version number.

import Sailfish.Silica 1.0
import QtQuick 2.0

Page {
    id: aboutPage

    SilicaFlickable {
        anchors.fill: parent
        contentWidth: parent.width
        contentHeight: col.height

        VerticalScrollDecorator {}

        Column {
            id: col
            width: parent.width
            spacing: Theme.paddingLarge

            PageHeader {
                title: qsTr("About Sailfactor 0.1")
            }

            SectionHeader {
                text: qsTr("License")
            }

            Label {
                anchors {
                    left: parent.left
                    right: parent.right
                    margins: Theme.paddingLarge
                }
                text: qsTr("[to be decided]")
            }

            SectionHeader {
                text: qsTr("Author")
            }

            Label {
                anchors {
                    left: parent.left
                    right: parent.right
                    margins: Theme.paddingLarge
                }
                text: "Lauri Nurmi <lanurmi@iki.fi>"
            }

            SectionHeader {
                text: qsTr("Source code")
            }

            Label {
                anchors {
                    left: parent.left
                    right: parent.right
                    margins: Theme.paddingLarge
                }
                text: qsTr("will soon be available at github")
                BackgroundItem {
                    anchors.fill: parent
                    onClicked: Qt.openUrlExternally("http://www.github.com/lanurmi/sailfactor")
                }
            }
        }
    }
}


import Qt 4.7
import no.trolltech.QmlModule01 1.0
import com.nokia.QmlModule02 1.0

Rectangle {
    width: 200
    height: 200
    color: "#ddddff"

    Text {
        id: title
        text: "main"
    }

    Column {
        anchors.fill: parent
        anchors.margins: title.height + 2

        QmlComponent01 {
            anchors.top: parent.top
            height: parent.height / 2
            width: parent.width
        }

        QmlComponent02 {
            anchors.bottom: parent.bottom
            height: parent.height / 2
            width: parent.width
        }
    }
}

Remove incorrect (and unneeded) anchoring

import Qt 4.7
import no.trolltech.QmlModule01 1.0
import com.nokia.QmlModule02 1.0

Rectangle {
    width: 200
    height: 200
    color: "#ddddff"

    Text {
        id: title
        text: "main"
    }

    Column {
        anchors.fill: parent
        anchors.margins: title.height + 2

        QmlComponent01 {
            height: parent.height / 2
            width: parent.width
        }

        QmlComponent02 {
            height: parent.height / 2
            width: parent.width
        }
    }
}


Item {
	height: 20;
	width: 173;
	property string text;

	onCompleted: {
		var input = $('<input type="text">');
		this.element.append(input)

		var inputs = document.getElementsByTagName('INPUT');
		var self = this;
		var func = function() {
			self.text = this.value;
		}

		inputs[inputs.length - 1].onkeyup = func;
	}
}

Fix text input: propagate key pressed handling.

Item {
	height: 20;
	width: 173;
	property string text;

	onCompleted: {
		var input = $('<input type="text">');
		input.width(this.width);
		input.height(this.height);
		var self = this
		input.keyup(function() { self.text = this.value } );
		input.keydown(function(event) { if (self._processKey(event)) event.preventDefault();} );
		this.element.append(input)
	}
}


import qbs

import "CommonProduct.qbs" as CommonProduct

CommonProduct {
	type: ["application", "autotest"]

	cutehmiType: "test"

	baseName: name

	condition: project.buildTests

	Properties {
		condition: qbs.targetOS.contains("linux")
		cpp.linkerFlags: "-rpath=$ORIGIN"
	}

	Depends { name: "Qt.testlib" }
	Depends { name: "Qt.qmltest" }

	Depends { name: "cutehmi.dirs" }

	Group {
		name: "Application"
		fileTagsFilter: "application"
		qbs.install: true
		qbs.installDir: cutehmi.dirs.testInstallDirname
	}

	cpp.defines: base.concat("QUICK_TEST_SOURCE_DIR=\"" + path + "\"")
}

//(c)MP: Copyright © 2018, Michal Policht. All rights reserved.
//(c)MP: This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

Make dependency on 'cutehmi_test_1' default.

import qbs

import "CommonProduct.qbs" as CommonProduct

CommonProduct {
	type: ["application", "autotest"]

	cutehmiType: "test"

	baseName: name

	condition: project.buildTests

	Properties {
		condition: qbs.targetOS.contains("linux")
		cpp.linkerFlags: "-rpath=$ORIGIN"
	}

	Depends { name: "Qt.testlib" }
	Depends { name: "Qt.qmltest" }

	Depends { name: "cutehmi_test_1" }
	cutehmi_test_1.reqMinor: 0

	Depends { name: "cutehmi.dirs" }

	Group {
		name: "Application"
		fileTagsFilter: "application"
		qbs.install: true
		qbs.installDir: cutehmi.dirs.testInstallDirname
	}

	cpp.defines: base.concat("QUICK_TEST_SOURCE_DIR=\"" + path + "\"")
}

//(c)MP: Copyright © 2018, Michal Policht. All rights reserved.
//(c)MP: This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.


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(/[<>&]/g, function(c) {
                    switch (c) {
                        case "&": return "&"
                        case "<": return "<"
                        case ">": return ">"
                    }})
                .replace(/`(.+)`/g, "$1")
        }
    }
}

Add line break and strikethrough

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>")
        }
    }
}


import QtQuick 2.0

QtObject {
    id: app

    // Properties
    property string text
    property string theme
    property string mode

    // Functions
    function spawn(screen, proto) {
        if (!proto)
            proto = windowPrototype

        var window = proto.createObject(app)
        Native.setScreen(window, screen)

        return window
    }

    // Events
    Component.onCompleted: {
        var screens = Native.getScreens()
        var primaryScreen = Native.getPrimaryScreen()

        if (screens.length > 1) {
            for (var i = 0; i < screens.length; i++)
                if (screens[i] != primaryScreen)
                    spawn(screens[i]) }
        else
            spawn(primaryScreen)

        var editor = spawn(primaryScreen, editorPrototype)
        editor.init()
    }

    // Resources
    property list<Component> resources: [
        Component {
            id: windowPrototype
            DisplayWindow {}
        },
        Component {
            id: editorPrototype
            EditorWindow {}
        }
    ]
}

Refactor code to make it more clear

import QtQuick 2.0

QtObject {
    id: app

    // Properties
    property string text
    property string theme
    property string mode

    // Functions
    function spawn(screen, proto) {
        if (!proto)
            proto = windowPrototype

        var window = proto.createObject(app)
        Native.setScreen(window, screen)

        return window
    }

    // Events
    Component.onCompleted: {
        var screens = Native.getScreens()
        var primaryScreen = Native.getPrimaryScreen()

        if (screens.length < 2)
            spawn(primaryScreen)
        else
            for (var i in screens)
                if (screens[i] !== primaryScreen)
                    spawn(screens[i])

        var editor = spawn(primaryScreen, editorPrototype)
        editor.init()
    }

    // Resources
    property list<Component> resources: [
        Component {
            id: windowPrototype
            DisplayWindow {}
        },
        Component {
            id: editorPrototype
            EditorWindow {}
        }
    ]
}


Item {
	property int value;
	property int min: 0;
	property int max: 100;
	property int step: 1;

	/// @private
	constructor: {
		this.element.dom.type = "range"
		this.element.on("input", function() { this.value = this.element.dom.value }.bind(this))
	}

	/// @private
	function _update(name, value) {
		switch (name) {
			case 'min': this.element.dom.min = value; break
			case 'max': this.element.dom.max = value; break
			case 'step': this.element.dom.step = value; break
		}

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

	/// returns tag for corresponding element
	function getTag() { return 'input' }
}

Set default height and value in Slider.

Item {
	property int value;
	property int min: 0;
	property int max: 100;
	property int step: 1;
	height: 30;

	/// @private
	constructor: {
		this.element.dom.type = "range"
		this.element.dom.value = 0
		this.element.on("input", function() { this.value = this.element.dom.value }.bind(this))
	}

	/// @private
	function _update(name, value) {
		switch (name) {
			case 'min': this.element.dom.min = value; break
			case 'max': this.element.dom.max = value; break
			case 'step': this.element.dom.step = value; break
		}

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

	/// returns tag for corresponding element
	function getTag() { return 'input' }
}


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

ApplicationWindow
{
    initialPage: FirstPage { }
    cover: Qt.resolvedUrl("cover/CoverPage.qml")
}

Change initial page via Qt.resolvedurl.

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

ApplicationWindow
{
    initialPage: Qt.resolvedUrl("pages/FirstPage.qml")
    cover: Qt.resolvedUrl("cover/CoverPage.qml")
}


import QtQuick 1.1
import org.kde.people 0.1
import org.kde.plasma.components 0.1
import org.kde.plasma.extras 0.1

Rectangle {
    width: 100
    height: 100
    color: "red"

    ListView {
        id: view
        anchors {
            top: parent.top
            bottom: parent.bottom
            left: parent.left
        }
        width: parent.width/2

        model: PersonsModel {}
        delegate:   ListItem {
                        Label {
                            anchors.fill: parent
                            elide: Text.ElideRight
                            text: display
                        }
                        enabled: true
                        onClicked: contactItem.contactData = model
                    }
    }

    Item {
        id: contactItem
        anchors {
            top: parent.top
            right: parent.right
            bottom: parent.bottom
        }
        width: parent.width/2
        property variant contactData
        onContactDataChanged: {
            var text = ""
            for(var a in contactData)
                text += a + ": " + contactData[a]+'\n'
            contactText.text = text
            console.log("contact selected:", text)
        }

        Label {
            id: contactText
            anchors.fill: parent
            text: "select a contact"
        }
    }
}

Improve the person data extraction

import QtQuick 1.1
import org.kde.people 0.1
import org.kde.plasma.components 0.1
import org.kde.plasma.extras 0.1

Rectangle {
    width: 100
    height: 100
    color: "red"

    ListView {
        id: view
        anchors {
            top: parent.top
            bottom: parent.bottom
            left: parent.left
        }
        width: parent.width/2

        model: PersonsModel {}
        delegate:   ListItem {
                        Label {
                            anchors.fill: parent
                            elide: Text.ElideRight
                            text: display
                        }
                        enabled: true
                        onClicked: contactItem.contactData = model
                    }
    }

    Item {
        id: contactItem
        anchors {
            top: parent.top
            right: parent.right
            bottom: parent.bottom
        }
        width: parent.width/2
        property variant contactData
        function dataToString(data) {
            var text = ""
            if(data.empty)
                text="''"
            for(var a in data) {
                text += a + ": ";
                var curr = data[a]
                if(curr==null)
                    text += "null"
                else if(!curr.isObject)
                    text += curr
                else
                    text += dataToString[curr]
                text += '\n'
            }
            return text
        }
        onContactDataChanged: {
            contactText.text = dataToString(contactData)
            console.log("contact selected:", contactText.text)
        }

        Label {
            id: contactText
            anchors.fill: parent
            text: "select a contact"
        }
    }
}


///number input
BaseInput {
	property float max;		///< maximum number value
	property float min;		///< minimum number value
	property float step;	///< number step value
	property float value;	///< number value
	horizontalAlignment: BaseInput.AlignHCenter;
	width: 50;
	height: 25;
	type: "number";

	onMinChanged: { this.element.dom.min = value; }
	onMaxChanged: { this.element.dom.max = value; }
	onStepChanged: { this.element.dom.step = value; }
	onValueChanged: { this.element.dom.value = value; }

	constructor: {
		this.element.on("input", function() {
			var currentValue = this.element.dom.value
			this.value = currentValue <= this.max && currentValue >= this.min ? currentValue : (currentValue > this.max ? this.max : this.min)
		}.bind(this))
	}
}

Fix init value setting: remove useless min max checking

///number input
BaseInput {
	property float max;		///< maximum number value
	property float min;		///< minimum number value
	property float step;	///< number step value
	property float value;	///< number value
	horizontalAlignment: BaseInput.AlignHCenter;
	width: 50;
	height: 25;
	type: "number";

	onMinChanged: { this.element.dom.min = value; }
	onMaxChanged: { this.element.dom.max = value; }
	onStepChanged: { this.element.dom.step = value; }
	onValueChanged: { this.element.dom.value = value; }

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


import Qt 4.7

TextInput {
    font.pointSize: 14
    color: "white"
    property string throttledText: ""
    property int throttleInterval: 500

    onTextChanged: {
        throttleTimer.restart()
    }

    Timer {
        id: throttleTimer
        interval: parent.throttleInterval
        repeat: false
        onTriggered: {
            parent.throttledText = parent.text
        }
    }
}

Use better ids in text input

import Qt 4.7

TextInput {
    id: input
    font.pointSize: 14
    color: "white"
    property string throttledText: ""
    property int throttleInterval: 500

    onTextChanged: {
        throttleTimer.restart()
    }

    Timer {
        id: throttleTimer
        interval: input.throttleInterval
        repeat: false
        onTriggered: {
            input.throttledText = input.text
        }
    }
}


import QtQuick 2.0
import QtTest 1.2
import UC 1.0

TestCase {
    name: "Test the Button"

    property bool buttonPressed : false

    Button {
        id : button
        text : "foo"
        onClicked : {
            buttonPressed = true
        }
    }

    function test_Button() {
        compare(button.text, "foo")
        compare(button.pressed, false)
        button.clicked()
        compare(buttonPressed, true)
    }
}

Adjust unit tests for Silica testing

import QtQuick 2.0
import QtTest 1.1
import UC 1.0

TestCase {
    name: "Test the Button"

    Button {
        id : button
        text : "foo"
        onClicked : {
            console.log("foo")
        }
    }

    function test_Button() {
        compare(button.text, "foo")
        compare(button.pressed, false)
        // check the onClicked property exists
        verify(button.onClicked)
    }
}


import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Dialogs 1.3

Item {
    id: root

    property string name
    property Setting setting

    implicitHeight: item.implicitHeight

    SettingItem {
        id: item

        name: root.name
        subtitle: setting.value
        anchors.fill: parent

        onClicked: dialog.open()

        FileDialog {
            id: dialog

            title: qsTr("Please choose a directory")
            folder: setting.value
            selectFolder: true

            onAccepted: setting.setValue(backend.toLocalFile(dialog.fileUrl.toString()))
        }
    }
}

Improve looks of Android paths

import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Dialogs 1.3

Item {
    id: root

    property string name
    property Setting setting

    implicitHeight: item.implicitHeight

    SettingItem {
        id: item

        name: root.name
        subtitle: setting.value.startsWith("/storage/emulated/0/")
            ? setting.value.substr(19)
            : setting.value
        anchors.fill: parent

        onClicked: dialog.open()

        FileDialog {
            id: dialog

            title: qsTr("Please choose a directory")
            folder: setting.value
            selectFolder: true

            onAccepted: setting.setValue(backend.toLocalFile(dialog.fileUrl.toString()))
        }
    }
}


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

ApplicationWindow
{
    id: appw
    initialPage: sailFactorComponent
    cover: Qt.resolvedUrl("cover/Cover.qml")
    Component {
        id: sailFactorComponent
        SailFactor {
            id: sailfactor
            Component.onCompleted: appw._sailfactor = sailfactor
        }
    }

    property SailFactor _sailfactor

    function getOutput() {
        if (_sailfactor._field.length === 0)
            return "" + qsTr("Enter an integer first.") + "";
        else
            return fact.factorize(parseInt(_sailfactor._field), _sailfactor._slider, true);
    }

    function nextStep() {
        if (_sailfactor._slider < 22) // FIXME: should read the real max from somewhere
            _sailfactor._slider ++;
    }

    function prevStep() {
        if (_sailfactor._slider > 0)
            _sailfactor._slider --;
    }
}

Use a less intimidating color and friendlier message in the cover when nothing has been entered yet.

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

ApplicationWindow
{
    id: appw
    initialPage: sailFactorComponent
    cover: Qt.resolvedUrl("cover/Cover.qml")
    Component {
        id: sailFactorComponent
        SailFactor {
            id: sailfactor
            Component.onCompleted: appw._sailfactor = sailfactor
        }
    }

    property SailFactor _sailfactor

    function getOutput() {
        if (_sailfactor._field.length === 0)
            return "" + qsTr("No integer entered yet.") + "";
        else
            return fact.factorize(parseInt(_sailfactor._field), _sailfactor._slider, true);
    }

    function nextStep() {
        if (_sailfactor._slider < 22) // FIXME: should read the real max from somewhere
            _sailfactor._slider ++;
    }

    function prevStep() {
        if (_sailfactor._slider > 0)
            _sailfactor._slider --;
    }
}


Add storer for saving App position information

import QtQuick 2.0
import QtQuick.LocalStorage 2.0 as Sql

Item {
    property var db

    Component.onCompleted: {
        db = Sql.LocalStorage.openDatabaseSync("Hangee", "1.0",
                                               "Database for Hangee", 100000)
        db.transaction(function (tx) {
            var query = "CREATE TABLE IF NOT EXISTS Position(AppID TEXT, DesktopID INTEGER, PositionID INTEGER)"
            tx.executeSql(query)
        })

        console.log(JSON.parse(select('aaa')).AppID)
    }

    function appInfo(AppID, DesktopID, PositionID) {
        this.AppID = AppID
        this.DesktopID = DesktopID
        this.PositionID = PositionID
    }

    function insert(AppID, DesktopID, PositionID) {
        db.transaction(function (tx) {
            var query = "INSERT INTO Position VALUES(?, ?, ?)"
            tx.executeSql(query, [AppID, DesktopID, PositionID])
        })
    }

    function select(AppID) {
        var jsondata
        db.transaction(function (tx) {
            var rs = tx.executeSql("SELECT * FROM Position WHERE AppID = ?",
                                   [AppID])

            for (var i = 0; i < rs.rows.length; i++) {
                jsondata = "{\"AppID\":\"" + rs.rows.item(
                            i).AppID + "\", \"DesktopID\":\"" + rs.rows.item(
                            i).DesktopID + "\", \"PositionID\":\"" + rs.rows.item(
                            i).PositionID + "\"}"
            }
        })
        return jsondata
    }
}


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

import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Rectangle
{
    width: 300; height: 100
    ColumnLayout
    {

        Text
        {
            text: {
                if (manager.progress == 0)
                {
                    //: Firmware update status label
                    return qsTr("Starting firmware update, this may take a while.")
                }
                else if (manager.progress > 99)
                {
                    //: Firmware update status label
                    return qsTr("Firmware update completed.")
                }
                else
                {
                    //: Firmware update status label
                    return qsTr("Updating firmware.")
                }
            }
        }
        ProgressBar
        {
            id: prog;
            value: manager.progress
            minimumValue: 0;
            maximumValue: 100;
            Layout.maximumWidth:parent.width
            Layout.preferredWidth:230
            Layout.preferredHeight:25
            Layout.minimumWidth:230
            Layout.minimumHeight:25
            width: 230
            height: 25
        }
    }
}

Improve styling of Firmware update window

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

import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Window 2.1

Rectangle
{
    id: base;

    width: 500 * Screen.devicePixelRatio;
    height: 100 * Screen.devicePixelRatio;

    color: palette.window;

    signal close();

    Column
    {
        anchors.fill: parent;
        anchors.margins: 8 * Screen.devicePixelRatio;
        Label
        {
            anchors {
                left: parent.left;
                right: parent.right;
            }

            text: {
                if (manager.progress == 0)
                {
                    //: Firmware update status label
                    return qsTr("Starting firmware update, this may take a while.")
                }
                else if (manager.progress > 99)
                {
                    //: Firmware update status label
                    return qsTr("Firmware update completed.")
                }
                else
                {
                    //: Firmware update status label
                    return qsTr("Updating firmware.")
                }
            }

            wrapMode: Text.Wrap;
        }
        ProgressBar
        {
            id: prog;
            value: manager.progress
            minimumValue: 0;
            maximumValue: 100;
            anchors {
                left: parent.left;
                right: parent.right;
            }

        }
        Button {
            anchors.right: parent.right;
            text: qsTr("Close");
            onClicked: base.close();
        }
    }

    SystemPalette {
        id: palette;
    }
}


import Qt 4.7

XmlListModel {
    property string tags : ""

    source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "")+"format=rss2"
    query: "/rss/channel/item"
    namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";"

    XmlRole { name: "title"; query: "title/string()" }
    XmlRole { name: "imagePath"; query: "media:thumbnail/@url/string()" }
    XmlRole { name: "url"; query: "media:content/@url/string()" }
    XmlRole { name: "description"; query: "description/string()" }
    XmlRole { name: "tags"; query: "media:category/string()" }
    XmlRole { name: "photoWidth"; query: "media:content/@width/string()" }
    XmlRole { name: "photoHeight"; query: "media:content/@height/string()" }
    XmlRole { name: "photoType"; query: "media:content/@type/string()" }
    XmlRole { name: "photoAuthor"; query: "author/string()" }
    XmlRole { name: "photoDate"; query: "pubDate/string()" }
}

Fix API call for multiple tags. Spec says comma, not eg. space separated.

import Qt 4.7

XmlListModel {
    property string tags : ""

    function commasep(x)
    {
        return x.replace(' ',',');
    }

    source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+commasep(tags)+"&" : "")+"format=rss2"
    query: "/rss/channel/item"
    namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";"

    XmlRole { name: "title"; query: "title/string()" }
    XmlRole { name: "imagePath"; query: "media:thumbnail/@url/string()" }
    XmlRole { name: "url"; query: "media:content/@url/string()" }
    XmlRole { name: "description"; query: "description/string()" }
    XmlRole { name: "tags"; query: "media:category/string()" }
    XmlRole { name: "photoWidth"; query: "media:content/@width/string()" }
    XmlRole { name: "photoHeight"; query: "media:content/@height/string()" }
    XmlRole { name: "photoType"; query: "media:content/@type/string()" }
    XmlRole { name: "photoAuthor"; query: "author/string()" }
    XmlRole { name: "photoDate"; query: "pubDate/string()" }
}


import QtQuick 2.8
import QtQuick.Controls 2.4

ToolButton {
    id: control
    checkable: true
    hoverEnabled: true

    ToolTip.visible: ToolTip.text && hovered
    ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval

    background: Rectangle {
        anchors.fill: parent
        color: Qt.darker(theme.highlightColor, control.enabled && (control.checked || control.highlighted) ? 1.5 : 1.0)
        opacity: enabled ? 1 : 0.3
        visible: control.down || (control.enabled && (control.checked || control.highlighted))
    }
}

Use base control: Button (fixes display issues with button text, etc.)

import QtQuick 2.8
import QtQuick.Controls 2.4

Button {
    id: control
    checkable: true
    hoverEnabled: true

    ToolTip.visible: ToolTip.text && hovered
    ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
}


import QtQuick 2.8
import QtQuick.Controls 2.2
import org.kde.kirigami 2.12 as Kirigami

Kirigami.ShadowedRectangle {
    id: root
    implicitWidth: img.width
    implicitHeight: img.height
    radius: 2
    color: 'transparent' // Kirigami.Theme.backgroundColor
//        property color borderColor: Kirigami.Theme.textColor
//        border.color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
//        border.width: 1
    shadow.xOffset: 1
    shadow.yOffset: 3
    shadow.color: Qt.rgba(0, 0, 0, 0.6)
    shadow.size: Kirigami.Units.largeSpacing

    property alias animateLoad: img.animateLoad
    property alias sourceKey: img.sourceKey
    property alias source: img.source
    property alias sourceUrl: img.sourceUrl
    property alias opacityTo: img.opacityTo
    property alias sourceSize: img.sourceSize
    property alias fillMode: img.fillMode
    property alias duration: img.duration
    property alias cache: img.cache
    property alias mipmap: img.mipmap
    property alias thumbnail: img.thumbnail

    signal statusChanged()
    signal imageError()

    TrackImage {
        id: img
        onStatusChanged: {
            if (img.status === Image.Error)
                root.imageError()
            root.statusChanged()
        }
    }
}

Use ShadowedTexture instead of ShadowedRect

import QtQuick 2.12
import QtQuick.Controls 2.2
import org.kde.kirigami 2.12 as Kirigami

Item {
    id: root
    implicitWidth: img.width
    implicitHeight: img.height

    property alias color: shadowRectangle.color
    property alias radius: shadowRectangle.radius
    property alias shadow: shadowRectangle.shadow
    property alias border: shadowRectangle.border
    property alias corners: shadowRectangle.corners

    property alias animateLoad: img.animateLoad
    property alias sourceKey: img.sourceKey
    property alias source: img.source
    property alias sourceUrl: img.sourceUrl
    property alias opacityTo: img.opacityTo
    property alias sourceSize: img.sourceSize
    property alias fillMode: img.fillMode
    property alias duration: img.duration
    property alias cache: img.cache
    property alias mipmap: img.mipmap
    property alias thumbnail: img.thumbnail

    signal statusChanged()
    signal imageError()

    TrackImage {
        id: img
        onStatusChanged: {
            if (img.status === Image.Error)
                root.imageError()
            root.statusChanged()
        }
    }

    Kirigami.ShadowedTexture {
         id: shadowRectangle
         anchors.fill: parent

         radius: 2
         color: 'transparent'
         shadow.xOffset: 1
         shadow.yOffset: 3
         shadow.color: Qt.rgba(0, 0, 0, 0.6)
         shadow.size: Kirigami.Units.largeSpacing

         source: img.status === Image.Ready ? img : null
     }}


import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1

Item {
    id: item1

    property int flags_width: 70
    property int flags_height: 36
    property alias usButton: usButton
    property alias japButton: japButton
    property alias frButton: frButton

    GridLayout {
        id: flags_grid
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        Image {
            id: select_FR
            width: flags_width
            height: flags_height
            fillMode: Image.PreserveAspectFit
            source: "images/flags/France.svg"
            sourceSize.width: flags_width
            sourceSize.height: flags_height

            MouseArea {
                id: frButton
                anchors.fill: parent
            }
        }

        Image {
            id: select_US
            width: flags_width
            height: flags_height
            fillMode: Image.PreserveAspectFit
            source: "images/flags/United_States.svg"
            sourceSize.width: flags_width
            sourceSize.height: flags_height
            MouseArea {
                id: usButton
                anchors.fill: parent
            }
        }

        Image {
            id: select_JAP
            width: flags_width
            height: flags_height
            fillMode: Image.PreserveAspectFit
            source: "images/flags/Japan.svg"
            sourceSize.width: flags_width
            sourceSize.height: flags_height

            MouseArea {
                id: japButton
                anchors.fill: parent
            }
        }
    }
}

Use GridView instead of GradLayout

import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1

Item {
    id: item1

    property int flags_width: 70
    property int flags_height: 36
    property alias usButton: usButton
    property alias japButton: japButton
    property alias frButton: frButton

    GridView {
        id: flags_grid
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        model: LanguageModel {}
        delegate: Image {
            source: flag_rsc
            width: flags_width
            height: flags_height
            fillMode: Image.PreserveAspectFit
            sourceSize.width: flags_width
            sourceSize.height: flags_height

            MouseArea {
                anchors.fill: parent
            }
        }
    }
}


import QtQuick 2.0
import Sailfish.Silica 1.0

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

Fix cover page icon url

import QtQuick 2.0
import Sailfish.Silica 1.0

CoverBackground {
    CoverPlaceholder {
        id: coverPlaceholder
        text: coverText
        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("PIV")
        }, {
            text: qsTr("Configure PINs")
        }, {
            text: qsTr("PIN")
        }]
    defaultCurrentPin: constants.pivDefaultPin
    hasCurrentPin: true
    maxLength: constants.pivPinMaxLength
    minLength: constants.pivPinMinLength

    onChangePin: {
        yubiKey.piv_change_pin(currentPin, newPin, function (resp) {
            if (resp.success) {
                pivSuccessPopup.open()
                views.pop()
            } else {
                if (resp.error === 'wrong pin') {
                    clearPinInputs()
                    pivError.show(qsTr("Wrong current PIN. Tries remaining: %1").arg(resp.tries_left))
                } else if (resp.error === 'blocked') {
                    pivError.show(qsTr("PIN is blocked. Use the PUK to unlock it, or reset the PIV application."))
                    views.pop()
                } else if (resp.error === 'incorrect parameters') {
                    clearNewPinInputs()
                    pivError.show(qsTr("Invalid PIN format. PIN must be %1 to %2 characters.").arg(minLength).arg(maxLength))
                } else {
                    pivGeneralError.error = resp.error
                    pivGeneralError.open()
                }
            }
        })
    }
}

Use pivError.show method instead of assigning error= and open()

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

ChangePinView {

    breadcrumbs: [{
            text: qsTr("PIV")
        }, {
            text: qsTr("Configure PINs")
        }, {
            text: qsTr("PIN")
        }]
    defaultCurrentPin: constants.pivDefaultPin
    hasCurrentPin: true
    maxLength: constants.pivPinMaxLength
    minLength: constants.pivPinMinLength

    onChangePin: {
        yubiKey.piv_change_pin(currentPin, newPin, function (resp) {
            if (resp.success) {
                pivSuccessPopup.open()
                views.pop()
            } else {
                if (resp.error === 'wrong pin') {
                    clearPinInputs()
                    pivError.show(qsTr("Wrong current PIN. Tries remaining: %1").arg(resp.tries_left))
                } else if (resp.error === 'blocked') {
                    pivError.show(qsTr("PIN is blocked. Use the PUK to unlock it, or reset the PIV application."))
                    views.pop()
                } else if (resp.error === 'incorrect parameters') {
                    clearNewPinInputs()
                    pivError.show(qsTr("Invalid PIN format. PIN must be %1 to %2 characters.").arg(minLength).arg(maxLength))
                } else {
                    pivError.show(resp.error)
                }
            }
        })
    }
}


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

import UM 1.0 as UM

import "../Preferences"

PreferencesPage {
    //: Machine configuration page title.
    title: qsTr("Machine");

    contents: ScrollView
    {
        anchors.fill: parent;
        ListView
        {
            delegate: settingDelegate
            model: UM.Models.settingsModel

            section.property: "category"
            section.delegate: Label { text: section }
        }
    }

    Component
    {
        id: settingDelegate
        CheckBox
        {
            text: model.name;
            x: depth * 25
            checked: model.visibility
            onClicked: ListView.view.model.setVisibility(model.key, checked)
            enabled: !model.disabled
        }
    }
}

Add an active machine selector to the machine configuration page

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

import UM 1.0 as UM

import "../Preferences"

PreferencesPage {
    //: Machine configuration page title.
    title: qsTr("Machine");

    contents: ColumnLayout {
        anchors.fill: parent;
        RowLayout {
            Label { text: qsTr("Active Machine:"); }
            ComboBox {
                id: machineCombo;
                Layout.fillWidth: true;
                model: UM.Models.machinesModel;
                textRole: "name";
                onCurrentIndexChanged: {
                    if(currentIndex != -1)
                        UM.Models.machinesModel.setActive(currentIndex);
                }

                Connections {
                    id: machineChange
                    target: UM.Application
                    onMachineChanged: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName);
                }

                Component.onCompleted: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName);
            }
            Button { text: qsTr("Remove"); }
        }
        ScrollView
        {
            Layout.fillWidth: true;
            Layout.fillHeight: true;

            ListView
            {
                delegate: settingDelegate
                model: UM.Models.settingsModel

                section.property: "category"
                section.delegate: Label { text: section }
            }
        }
    }

    Component
    {
        id: settingDelegate
        CheckBox
        {
            text: model.name;
            x: depth * 25
            checked: model.visibility
            onClicked: ListView.view.model.setVisibility(model.key, checked)
            enabled: !model.disabled
        }
    }
}


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; 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)
	}
}

Call highlightBlock also when language is changed.

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)
	}
}


import Grabber 1.0
import QtQml 2.12
import QtQuick 2.12
import QtQuick.Controls 2.5

FocusScope {
    id: root

    signal enterPressed()
    property alias text: textInput.fakeText
    property alias placeholderText: textInput.placeholderText
    property bool isOpen: false

    activeFocusOnTab: true

    Rectangle {
        id: editbg
        anchors.fill: parent
        anchors.topMargin: 8
        anchors.bottomMargin: 8
        color: Qt.rgba(1, 1, 1, 0.6)
        radius: 12

        AutoCompleteSearchEdit {
            id: textInput

            anchors.fill: parent
            anchors.leftMargin: 12
            anchors.rightMargin: 12
            focus: true

            property string fakeText
            onFakeTextChanged: textInput.setText(fakeText)

            onEnterPressed: root.enterPressed()
        }

        ToolButton {
            icon.source: root.isOpen
                ? "/images/icons/remove.png"
                : "/images/icons/add.png"
            onClicked: root.isOpen = !root.isOpen
            flat: true
            height: 34
            width: 34
            anchors.right: editbg.right
            anchors.verticalCenter: editbg.verticalCenter
        }
    }
}

Fix search not using tags

import Grabber 1.0
import QtQml 2.12
import QtQuick 2.12
import QtQuick.Controls 2.5

FocusScope {
    id: root

    signal enterPressed()
    property alias text: textInput.fakeText
    property alias placeholderText: textInput.placeholderText
    property bool isOpen: false

    activeFocusOnTab: true

    Rectangle {
        id: editbg
        anchors.fill: parent
        anchors.topMargin: 8
        anchors.bottomMargin: 8
        color: Qt.rgba(1, 1, 1, 0.6)
        radius: 12

        AutoCompleteSearchEdit {
            id: textInput

            anchors.fill: parent
            anchors.leftMargin: 12
            anchors.rightMargin: 12
            focus: true

            property string fakeText
            property bool blockTextChanges: false
            onFakeTextChanged: {
                if (blockTextChanges) {
                    blockTextChanges = false
                    return
                }
                textInput.setText(fakeText)
            }
            onTextChanged: {
                blockTextChanges = true
                fakeText = text
            }

            onEnterPressed: root.enterPressed()
        }

        ToolButton {
            icon.source: root.isOpen
                ? "/images/icons/remove.png"
                : "/images/icons/add.png"
            onClicked: root.isOpen = !root.isOpen
            flat: true
            height: 34
            width: 34
            anchors.right: editbg.right
            anchors.verticalCenter: editbg.verticalCenter
        }
    }
}


import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4

Window {
    id: root
    visible: true
    width: Screen.desktopAvailableWidth
    height: Screen.desktopAvailableHeight
    title: qsTr("Input gesture")

    flags: Qt.FramelessWindowHint | Qt.WA_TranslucentBackground

    color: Qt.rgba(0, 0, 0, 0.2)

    MouseArea {
        anchors.fill: parent

        onPressed: pieMenu.popup(Screen.desktopAvailableWidth / 2, Screen.desktopAvailableHeight / 2)
    }

    PieMenu {
        id: pieMenu
        objectName: "pieMenu"

        width: Screen.desktopAvailableWidth / 1.5
        height: Screen.desktopAvailableHeight / 1.5

        triggerMode: TriggerMode.TriggerOnRelease

        style: PieMenuStyle {
            startAngle: 0
            endAngle: 360
        }

        Component.onCompleted: {
            var itemKeys = pieMenuItems.keys();

            for (var i = 0; i < itemKeys.length; i++) {
                var menuItem = itemKeys[i];
                var newItem = pieMenu.addItem(menuItem);
                newItem.iconSource = applicationPath + "/icons/" + pieMenuItems[menuItem];
            }
            pieMenu.update();
        }
    }
}

Implement hack to make pie menu appear on PieMenu QML launch

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4

Window {
    id: root
    visible: true
    width: Screen.desktopAvailableWidth
    height: Screen.desktopAvailableHeight
    title: qsTr("Input gesture")

    flags: Qt.FramelessWindowHint | Qt.WA_TranslucentBackground

    color: Qt.rgba(0, 0, 0, 0.2)

    // FIXME: This timer is a hack, but doing pieMenu.popup() in pieMenu's
    // Component.onCompleted simply does not work. So we do it with a
    // 1 ms delay.
    Timer {
        id: pressAndHoldTimer
        interval: 1
        onTriggered: pieMenu.popup(root.width / 2, root.height / 2);
    }

    PieMenu {
        id: pieMenu

        width: Screen.desktopAvailableWidth / 1.5
        height: Screen.desktopAvailableHeight / 1.5

        triggerMode: TriggerMode.TriggerOnRelease

        style: PieMenuStyle {
            startAngle: 0
            endAngle: 360
        }

        Component.onCompleted: {
            var itemKeys = pieMenuItems.keys();

            for (var i = 0; i < itemKeys.length; i++) {
                var menuItem = itemKeys[i];
                var newItem = pieMenu.addItem(menuItem);
                newItem.iconSource = applicationPath + "/icons/" + pieMenuItems[menuItem];
            }
            pieMenu.update();
            pressAndHoldTimer.start();
        }
    }
}


MouseArea {
	property float value: 0;
	width: 30;
	height: 100;

	Rectangle {
		width: 5;
		height: parent.height;
		anchors.horizontalCenter: parent.horizontalCenter;
		color: colorTheme.backgroundColor;
	}

	Rectangle {
		y: parent.height * (1.0 - parent.value) - height / 2;
		height: 10;
		width: parent.width;
		anchors.horizontalCenter: parent.horizontalCenter;
		color: "#fff";
	}

	onClicked: { this.value = 1.0 - this.mouseY / this.height; }
}

Update trackbar value on dragged.

MouseArea {
	property float value: 0;
	width: 30;
	height: 100;
	hoverEnabled: true;

	Rectangle {
		width: 5;
		height: parent.height;
		anchors.horizontalCenter: parent.horizontalCenter;
		color: colorTheme.backgroundColor;
	}

	Rectangle {
		y: parent.height * (1.0 - parent.value) - height / 2;
		height: 10;
		width: parent.width;
		anchors.horizontalCenter: parent.horizontalCenter;
		color: "#fff";
	}

	onMouseYChanged: {
		if (this.pressed)
			this.value = 1.0 - this.mouseY / this.height;
	}
}


import QtQuick 2.7

Item {
    id: item1
    property int tile_text_spacing: 20
    property string tile_text: 'Tile'
    property string tile_color: 'grey'

    Text {
        id: main_text
        text: qsTr(tile_text)
        anchors.right: parent.right
        anchors.left: parent.left
        anchors.leftMargin: 0
        anchors.rightMargin: 0
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        anchors.top: parent.top
        anchors.topMargin: tile_text_spacing
        z: 1
    }

    Rectangle {
        id: background
        anchors.fill: parent
        color: tile_color
        z: 0
    }

}

Remove useless ID in generic tile

import QtQuick 2.7

Item {
    property int tile_text_spacing: 20
    property string tile_text: 'Tile'
    property string tile_color: 'grey'

    Text {
        id: main_text
        text: qsTr(tile_text)
        anchors.right: parent.right
        anchors.left: parent.left
        anchors.leftMargin: 0
        anchors.rightMargin: 0
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        anchors.top: parent.top
        anchors.topMargin: tile_text_spacing
        z: 1
    }

    Rectangle {
        id: background
        anchors.fill: parent
        color: tile_color
        z: 0
    }

}


/// mixin for wheel events
Object {
	signal wheel;	///< wheel move signal
	property bool enabled: true;	///< enable mixin

	///@private
	constructor: {
		this.element = this.parent.element;
		this._bindWheel(this.enabled)
	}

	///@private
	function _bindWheel(value) {
		if (value && !this._wheelBinder) {
			this._wheelBinder = new _globals.core.EventBinder(this.parent.element)
			this._wheelBinder.on('wheel', _globals.core.createSignalForwarder(this.parent, 'wheel').bind(this))
		}
		if (this._wheelBinder)
			this._wheelBinder.enable(value)
	}

	///@private
	onEnabledChanged: { this._bindWheel(value) }
}

Handle 'mousewheel' event too for deprecated browsers

/// mixin for wheel events
Object {
	signal wheel;	///< wheel move signal
	property bool enabled: true;	///< enable mixin

	///@private
	constructor: {
		this.element = this.parent.element;
		this._bindWheel(this.enabled)
	}

	///@private
	function _bindWheel(value) {
		if (value && !this._wheelBinder) {
			this._wheelBinder = new _globals.core.EventBinder(this.parent.element)
			this._wheelBinder.on('wheel', _globals.core.createSignalForwarder(this.parent, 'wheel').bind(this))
			this._wheelBinder.on('mousewheel', _globals.core.createSignalForwarder(this.parent, 'wheel').bind(this))
		}
		if (this._wheelBinder)
			this._wheelBinder.enable(value)
	}

	///@private
	onEnabledChanged: { this._bindWheel(value) }
}


import QtQuick 2.9

QtObject {
    readonly property int fido2PinMinLength: 4
    readonly property int fido2PinMaxLength: 128
    readonly property int pivPinMinLength: 4
    readonly property int pivPinMaxLength: 8
    readonly property int pivPukMinLength: 4
    readonly property int pivPukMaxLength: 8
    readonly property int h1: 32
    readonly property int h2: 24
    readonly property int h3: 18
    readonly property int h4: 14
    readonly property string fontFamily: "Helvetica Neue"

    readonly property int contentMargins: 40
    readonly property int contentTopMargin: 20
    readonly property int contentBottomMargin: 20
    readonly property int contentWidth: app.width - 80
    readonly property int contentHeight: app.height - header.height - 40
}

Fix PIV PIN/PUK minimum lengths

import QtQuick 2.9

QtObject {
    readonly property int fido2PinMinLength: 4
    readonly property int fido2PinMaxLength: 128
    readonly property int pivPinMinLength: 6
    readonly property int pivPinMaxLength: 8
    readonly property int pivPukMinLength: 6
    readonly property int pivPukMaxLength: 8
    readonly property int h1: 32
    readonly property int h2: 24
    readonly property int h3: 18
    readonly property int h4: 14
    readonly property string fontFamily: "Helvetica Neue"

    readonly property int contentMargins: 40
    readonly property int contentTopMargin: 20
    readonly property int contentBottomMargin: 20
    readonly property int contentWidth: app.width - 80
    readonly property int contentHeight: app.height - header.height - 40
}


ListModel {
	property Protocol protocol;

	update: {
		var self = this;
		this.protocol.getChannels(function(list) {
			self.clear();

			var map = {};
			var defaultName = "Разное";
			for (var i in list)
			{
				if (list[i].genre)
				{
					if (!map[list[i].genre])
						map[list[i].genre] = [];
					map[list[i].genre].push(list[i]);
				}
				else
				{
					if (!map[defaultName])
						map[defaultName] = [];
					map[defaultName].push(list[i]);
				}
			}

			for (var genre in map)
				self.append({ text: genre, list: map[genre] });
		})
	}

	onProtocolChanged: { this.update(); }
	onCompleted: { this.update(); }
}

Support multi genres in model filling.

ListModel {
	property Protocol protocol;

	update: {
		var self = this;
		this.protocol.getChannels(function(list) {
			self.clear();

			var map = {};
			var defaultName = "Разное";
			for (var i in list) {
				if (!list[i].genres || list[i].genres.length == 0) {
					if (!map[defaultName])
						map[defaultName] = [];
					map[defaultName].push(list[i]);
				} else {
					for (var j in list[i].genres) {
						var genre = list[i].genres[j];
						if (!map[genre])
							map[genre] = [];
						map[genre].push(list[i]);
					}
				}
			}

			for (var genre in map)
				self.append({ text: genre, list: map[genre] });
		})
	}

	onProtocolChanged: { this.update(); }
	onCompleted: { this.update(); }
}


import QtQuick.XmlListModel 2.0

BaseXml {
    property string queryField
    property string mediaType: 'audio'

    onQueryFieldChanged: reset()
    onHostUrlChanged: reset()
    onMediaTypeChanged: reset()

    function reset() {
        load("Library/Values?Field=%1&Files=[Media Type]=[%2]".arg(queryField).arg(mediaType))
    }

    XmlRole { name: "value"; query: "string()" }
}

Refactor for "audio only" or "all types" searching

import QtQuick.XmlListModel 2.0

BaseXml {
    property string queryField: 'artist'
    property string mediaType: 'audio'

    onQueryFieldChanged: reset()
    onHostUrlChanged: reset()
    onMediaTypeChanged: reset()

    function reset() {
        load("Library/Values?Field=%1%2".arg(queryField).arg(mediaType !== '' ? '&Files=[Media Type]=[%1]'.arg(mediaType) : ''))
    }

    XmlRole { name: "value"; query: "string()" }
}


/****************************************************************************
**
** Copyright (C) 2014 Jolla Ltd.
** Contact: Siteshwar Vashisht <siteshwar AT gmail.com>
** Contact: Raine Makelainen <raine.makelainen@jolla.com>
**
****************************************************************************/

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

import QtQuick 2.2
import Sailfish.Silica 1.0

ConfirmDialog {
    property Item browserPage

    //: Warning of changing browser configurations.
    //% "Changing these advanced settings can cause issues with stability, security and performance of Sailfish Browser. Continue ?"
    text: qsTrId("sailfish_browser-la-config-warning");
    acceptDestinationAction: PageStackAction.Replace
    acceptDestination: Component {
        ConfigDialog {
            // On accept pop back to browserPage
            acceptDestination: browserPage
            acceptDestinationAction: PageStackAction.Pop
        }
    }
}

Remove PageStackAction.Replace for about:config dialog. Fixes JB32873

/****************************************************************************
**
** Copyright (C) 2014 Jolla Ltd.
** Contact: Siteshwar Vashisht <siteshwar AT gmail.com>
** Contact: Raine Makelainen <raine.makelainen@jolla.com>
**
****************************************************************************/

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

import QtQuick 2.2
import Sailfish.Silica 1.0

ConfirmDialog {
    property Item browserPage

    //: Warning of changing browser configurations.
    //% "Changing these advanced settings can cause issues with stability, security and performance of Sailfish Browser. Continue ?"
    text: qsTrId("sailfish_browser-la-config-warning");
    acceptDestination: Component {
        ConfigDialog {
            // On accept pop back to browserPage
            acceptDestination: browserPage
            acceptDestinationAction: PageStackAction.Pop
        }
    }
}


/*
 * 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 TelepathyQML 0.1

Item {
    height:  12
    width: 12
    property int status: 0

    onStatusChanged: {
        iconImage.source = iconImage.statusIcon(status);
    }

    Image {
        id: iconImage
        height: parent.height
        width: parent.width
        source: statusIcon(parent.status)
        anchors.verticalCenter: parent.verticalCenter
        smooth: true

        function statusIcon(type) {
            var icon
            switch (type) {
            case TelepathyTypes.ConnectionPresenceTypeAvailable:
                icon = "image://meegotheme/widgets/apps/contacts/contact-available";
                break;
            case TelepathyTypes.ConnectionPresenceTypeBusy:
                icon = "image://meegotheme/widgets/apps/contacts/contact-busy";
                break;
            case TelepathyTypes.ConnectionPresenceTypeAway:
            case TelepathyTypes.ConnectionPresenceTypeExtendedAway:
                icon = "image://meegotheme/widgets/apps/contacts/contact-idle";
                break;
            case TelepathyTypes.ConnectionPresenceTypeHidden:
            case TelepathyTypes.ConnectionPresenceTypeUnknown:
            case TelepathyTypes.ConnectionPresenceTypeError:
            default:
                icon = "image://meegotheme/widgets/apps/contacts/contact-unavailable";
                break;
            }
            return icon;
        }
    }
}

Remove icon when contact is offline or unknown

/*
 * 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 TelepathyQML 0.1

Item {
    height:  12
    width: 12
    property int status: 0

    onStatusChanged: {
        iconImage.source = iconImage.statusIcon(status);
    }

    Image {
        id: iconImage
        height: parent.height
        width: parent.width
        source: statusIcon(parent.status)
        anchors.verticalCenter: parent.verticalCenter
        smooth: true

        function statusIcon(type) {
            var icon
            switch (type) {
            case TelepathyTypes.ConnectionPresenceTypeAvailable:
                icon = "image://meegotheme/widgets/apps/contacts/contact-available";
                break;
            case TelepathyTypes.ConnectionPresenceTypeBusy:
                icon = "image://meegotheme/widgets/apps/contacts/contact-busy";
                break;
            case TelepathyTypes.ConnectionPresenceTypeAway:
            case TelepathyTypes.ConnectionPresenceTypeExtendedAway:
                icon = "image://meegotheme/widgets/apps/contacts/contact-idle";
                break;
            case TelepathyTypes.ConnectionPresenceTypeHidden:
            case TelepathyTypes.ConnectionPresenceTypeUnknown:
            case TelepathyTypes.ConnectionPresenceTypeError:
            default:
                icon = "";
                break;
            }
            return icon;
        }
    }
}


import Grabber 1.0
import QtQuick 2.12
import QtQuick.Controls 2.5

TextEdit {
    id: root

    signal enterPressed()
    property alias placeholderText: placeholder.text

    verticalAlignment: Text.AlignVCenter
    font.pixelSize: 14

    Keys.onEnterPressed: {
        root.enterPressed()
        event.accepted = true
    }
    Keys.onReturnPressed: {
        root.enterPressed()
        event.accepted = true
    }

    Text {
        id: placeholder

        anchors.fill: parent
        verticalAlignment: Text.AlignVCenter
        visible: !(parent.text.length || parent.inputMethodComposing)
        font: parent.font
        color: "#666"
    }

    SyntaxHighlighterHelper {
        quickDocument: root.textDocument
    }
}

Hide keyboard on enter key press

import Grabber 1.0
import QtQuick 2.12
import QtQuick.Controls 2.5

TextEdit {
    id: root

    signal enterPressed()
    property alias placeholderText: placeholder.text

    verticalAlignment: Text.AlignVCenter
    font.pixelSize: 14

    Keys.onEnterPressed: {
        Qt.inputMethod.hide()
        root.enterPressed()
        event.accepted = true
    }
    Keys.onReturnPressed: {
        Qt.inputMethod.hide()
        root.enterPressed()
        event.accepted = true
    }

    Text {
        id: placeholder

        anchors.fill: parent
        verticalAlignment: Text.AlignVCenter
        visible: !(parent.text.length || parent.inputMethodComposing)
        font: parent.font
        color: "#666"
    }

    SyntaxHighlighterHelper {
        quickDocument: root.textDocument
    }
}


import qbs.base 1.0

GenericGCC {
    condition: qbs.hostOS == 'linux' && qbs.targetOS == 'linux' && qbs.toolchain == 'gcc'
}

Allow cross-compilation for Linux on non-Linux host.

import qbs.base 1.0

GenericGCC {
    condition: qbs.targetOS == 'linux' && qbs.toolchain == 'gcc'
}


/****************************************************************************
 *   Copyright (C) 2012  Instituto Nokia de Tecnologia (INdT)               *
 *                                                                          *
 *   This file may be used under the terms of the GNU Lesser                *
 *   General Public License version 2.1 as published by the Free Software   *
 *   Foundation and appearing in the file LICENSE.LGPL included in the      *
 *   packaging of this file.  Please review the following information to    *
 *   ensure the GNU Lesser General Public License version 2.1 requirements  *
 *   will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.   *
 *                                                                          *
 *   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.                    *
 ****************************************************************************/

import com.nokia.meego 2.0

PageStackWindow {
    initialPage: Page {
        orientationLock: PageOrientation.LockPortrait
        Main {
            anchors.fill: parent
        }
    }
}

Hide status bar until Qt5 orientation is fixed

/****************************************************************************
 *   Copyright (C) 2012  Instituto Nokia de Tecnologia (INdT)               *
 *                                                                          *
 *   This file may be used under the terms of the GNU Lesser                *
 *   General Public License version 2.1 as published by the Free Software   *
 *   Foundation and appearing in the file LICENSE.LGPL included in the      *
 *   packaging of this file.  Please review the following information to    *
 *   ensure the GNU Lesser General Public License version 2.1 requirements  *
 *   will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.   *
 *                                                                          *
 *   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.                    *
 ****************************************************************************/

import com.nokia.meego 2.0

PageStackWindow {
    // Hiding the status bar until the Orientation problems on N9 are fixed.
    // Tentative fix: https://codereview.qt-project.org/#change,24423
    showStatusBar: false

    initialPage: Page {
        orientationLock: PageOrientation.LockPortrait
        Main {
            anchors.fill: parent
        }
    }
}


// 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"}
}

Fix button to open OctoPrint from 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].toString().indexOf("OctoPrintOutputDevice") == 0

    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"}
}


import qbs

Product {
	targetName: qbs.buildVariant.contains("debug") ? name + "d" : name

	property stringList buildDefines: ["QT_DEPRECATED_WARNINGS"]

	property string vendor					///< Product vendor.

	property string friendlyName			///< Descriptive product name for ordinary humans.

	property string description				///< Product description.

	property string author					///< Author(s).

	property string copyright				///< Copyright holder(s).

	property string license					///< License(s).

	property string baseName

	property int major

	property int minor

	property int micro

	Properties {
		condition: qbs.buildVariant.contains("debug")
		cpp.defines: outer.concat(["CUTEHMI_DEBUG"]).concat(buildDefines)
	}

	Properties {
		condition: !qbs.buildVariant.contains("debug")
		cpp.defines: outer.concat(["CUTEHMI_RELEASE", "QT_NO_DEBUG_OUTPUT"]).concat(buildDefines)
	}
}

Add comment for `baseName` property and update license.

import qbs

Product {
	targetName: qbs.buildVariant.contains("debug") ? name + "d" : name

	property stringList buildDefines: ["QT_DEPRECATED_WARNINGS"]

	property string vendor					///< Product vendor.

	property string friendlyName			///< Descriptive product name for ordinary humans.

	property string description				///< Product description.

	property string author					///< Author(s).

	property string copyright				///< Copyright holder(s).

	property string license					///< License(s).

	property string baseName				///< Base name of the product (without the major version suffix).

	property int major

	property int minor

	property int micro

	Properties {
		condition: qbs.buildVariant.contains("debug")
		cpp.defines: outer.concat(["CUTEHMI_DEBUG"]).concat(buildDefines)
	}

	Properties {
		condition: !qbs.buildVariant.contains("debug")
		cpp.defines: outer.concat(["CUTEHMI_RELEASE", "QT_NO_DEBUG_OUTPUT"]).concat(buildDefines)
	}
}

//(c)MP: Copyright  2018, Michal Policht. All rights reserved.
//(c)MP: This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.


import QtQuick 2.0

Item {
    id: knob
    property string label: "color"
    property real percentage: 0

    width: scaleIndicator.width
    height: labelText.y + labelText.height - scaleIndicator.y

    Image {
        id: knobBase
        source: "../../resources/icons/btn.png"
        anchors.centerIn: scaleIndicator
        anchors.verticalCenterOffset: 14
        rotation: knob.percentage * 90

        Image {
            source: "../../resources/icons/incavo.png"
            anchors.top: knobBase.top
            anchors.topMargin: 2
            anchors.horizontalCenter: knobBase.horizontalCenter
            rotation: -knobBase.rotation
        }
    }

    MouseArea {
        anchors.fill: parent
        onPositionChanged: {
            var mouseRelative = mouse.x - knobBase.width / 2
            var percentage = Math.min(Math.max(-1, mouseRelative / (knobBase.width / 2)), 1)
            knob.percentage = percentage
        }
    }

    Image {
        id: scaleIndicator
        source: "../../resources/icons/indicatore.png"
    }

    Text {
        id: labelText

        anchors {
            top: knobBase.bottom
            topMargin: 20
            horizontalCenter: knobBase.horizontalCenter
        }

        text: knob.label
        color: "#939393"
        font.pointSize: 14
    }
}

Move the knob description up a bit

import QtQuick 2.0

Item {
    id: knob
    property string label: "color"
    property real percentage: 0

    width: scaleIndicator.width
    height: labelText.y + labelText.height - scaleIndicator.y

    Image {
        id: knobBase
        source: "../../resources/icons/btn.png"
        anchors.centerIn: scaleIndicator
        anchors.verticalCenterOffset: 14
        rotation: knob.percentage * 90

        Image {
            source: "../../resources/icons/incavo.png"
            anchors.top: knobBase.top
            anchors.topMargin: 2
            anchors.horizontalCenter: knobBase.horizontalCenter
            rotation: -knobBase.rotation
        }
    }

    MouseArea {
        anchors.fill: parent
        onPositionChanged: {
            var mouseRelative = mouse.x - knobBase.width / 2
            var percentage = Math.min(Math.max(-1, mouseRelative / (knobBase.width / 2)), 1)
            knob.percentage = percentage
        }
    }

    Image {
        id: scaleIndicator
        source: "../../resources/icons/indicatore.png"
    }

    Text {
        id: labelText

        anchors {
            top: knobBase.bottom
            topMargin: 6
            horizontalCenter: knobBase.horizontalCenter
        }

        text: knob.label
        color: "#939393"
        font.pointSize: 14
    }
}


import qbs
import qbs.File

Product {
    name: "qbs resources"
    Group {
        files: ["qbs"]
        qbs.install: true
        qbs.installDir: project.resourcesInstallDir + "/share"
    }

    Group {
        files: "../examples"
        qbs.install: true
        qbs.installDir: project.resourcesInstallDir + "/share/qbs"
    }

    Transformer {
        inputs: "qbs"
        Artifact {
            filePath: "share/qbs"
        }
        prepare: {
            var cmd = new JavaScriptCommand();
            cmd.description = "Copying share/qbs to build directory.";
            cmd.highlight = "codegen";
            cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }
            return cmd;
        }
    }
}

Fix qbs build of API autotest.

import qbs
import qbs.File

Product {
    name: "qbs resources"
    Group {
        files: ["qbs"]
        qbs.install: true
        qbs.installDir: project.resourcesInstallDir + "/share"
    }

    Group {
        files: "../examples"
        qbs.install: true
        qbs.installDir: project.resourcesInstallDir + "/share/qbs"
    }

    Transformer {
        inputs: "qbs"
        Artifact {
            filePath: project.buildDirectory + project.resourcesInstallDir + "/share/qbs"
        }
        prepare: {
            var cmd = new JavaScriptCommand();
            cmd.description = "Copying share/qbs to build directory.";
            cmd.highlight = "codegen";
            cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }
            return cmd;
        }
    }
}


/*
The MIT License (MIT)

Copyright (c) 2014-2018 Oleg Linkin <maledictusdemagog@gmail.com>
Copyright (c) 2017-2018 Maciej Janiszewski <chleb@krojony.pl>

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.0
import Sailfish.Silica 1.0
import harbour.linksbag 1.0

Item {
    property bool bookmarkRead: bookmark ? bookmark.read : false
    property bool bookmarkFavorite: bookmark ? bookmark.favorite : false
    property string publishedDate

    SilicaWebView {
        id: webView

        anchors.fill: parent

        PullDownMenu {
            MenuItem {
                text: bookmarkRead ?
                        qsTr("Mark as unread") :
                        qsTr("Mark as read")

                onClicked: {
                    linksbagManager.markAsRead(bookmark.id, !bookmarkRead)
                }
            }

            MenuItem {
                text: bookmarkFavorite ?
                        qsTr("Mark as unfavorite") :
                        qsTr("Mark as favorite")
                onClicked: {
                    linksbagManager.markAsFavorite(bookmark.id, !bookmarkFavorite)
                }
            }

            MenuItem {
                text: qsTr("Open in browser")
                onClicked: {
                    Qt.openUrlExternally(encodeURI(bookmark.url))
                }
            }
        }

        experimental.preferences.webGLEnabled: true
        experimental.preferences.notificationsEnabled: true
        experimental.preferences.javascriptEnabled: true
        experimental.preferences.navigatorQtObjectEnabled: true

        url: bookmark ? bookmark.url : ""
    }

    BusyIndicator {
        id: busyIndicator
        size: BusyIndicatorSize.Large
        anchors.centerIn: parent
        running: webView.loading || linksbagManager.busy
        visible: running
    }
}


// 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: UM.Theme.colors.setting_unit
                source: UM.Theme.icons.settings
            }
            label: Label{}
        }
        onClicked: {
            preferences.visible = true;
            preferences.setPage(2);
        }
    }
}

Add hover cursor shape to category header

// 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;

    MouseArea {
        anchors.fill: parent
        cursorShape: Qt.PointingHandCursor
        acceptedButtons: Qt.NoButton
    }

    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: UM.Theme.colors.setting_unit
                source: UM.Theme.icons.settings
            }
            label: Label{}
        }
        onClicked: {
            preferences.visible = true;
            preferences.setPage(2);
        }
        MouseArea {
            anchors.fill: parent
            cursorShape: Qt.PointingHandCursor
            acceptedButtons: Qt.NoButton
        }
    }
}


import QtQuick 2.5
import QtQuick.Controls 1.4

DefaultDialog {

    title: qsTr("Status for OpenPGP")
    property var device
    property var openPgpVersion
    property var pinRetries
    property var resetCodeRetries
    property var adminPinRetries

    Label {
        text: qsTr("OpenPGP")
        font.bold: true
    }
    Label {
        text: qsTr("Version: ") + (openPgpVersion ? openPgpVersion.join(
                                                        '.') : '')
    }
    Label {
        text: qsTr("PIN retries remaining: ") + pinRetries
    }
    Label {
        text: qsTr("Reset Code retries remaining: ") + resetCodeRetries
    }
    Label {
        text: qsTr("Admin PIN retries reamining: ") + adminPinRetries
    }

    function load() {
        device.openpgp_get_version(function (version) {
            openPgpVersion = version
            device.openpgp_get_remaining_pin_retries(function (retries) {
                pinRetries = retries[0]
                resetCodeRetries = retries[1]
                adminPinRetries = retries[2]
                show()
            })
        })
    }
}

Revert "Don't assign string to int"

import QtQuick 2.5
import QtQuick.Controls 1.4

DefaultDialog {

    title: qsTr("Status for OpenPGP")
    property var device
    property var openPgpVersion
    property int pinRetries
    property int resetCodeRetries
    property int adminPinRetries

    Label {
        text: qsTr("OpenPGP")
        font.bold: true
    }

    Label {
        text: qsTr("Version: ") + (openPgpVersion ? openPgpVersion.join('.') : '')
    }

    Label {
        text: qsTr("PIN retries remaining: ") + pinRetries
    }
    Label {
        text: qsTr("Reset Code retries remaining: ") + resetCodeRetries
    }
    Label {
        text: qsTr("Admin PIN retries reamining: ") + adminPinRetries
    }

    function load() {
        device.openpgp_get_version(function (version) {
            openPgpVersion = version
            device.openpgp_get_remaining_pin_retries(function (retries) {
                pinRetries = retries[0]
                resetCodeRetries = retries[1]
                adminPinRetries = retries[2]
                show()
            })
        })
    }
}


/// this mixin provides mouse hover events handling
BaseMouseMixin {
	property bool value;			///< is 'true' if item if hovered, 'false' otherwise

	///@private
	constructor: {
		this.element = this.parent.element;
		this.parent.style('cursor', this.cursor)
		this._bindHover(this.enabled)
	}

	///@private
	function _bindHover(value) {
		if (value && !this._hmHoverBinder) {
			this._hmHoverBinder = new $core.EventBinder(this.parent.element)

			if (this._context.backend.capabilities.mouseEnterLeaveSupported) {
				this._hmHoverBinder.on('mouseenter', function() { this.value = true }.bind(this))
				this._hmHoverBinder.on('mouseleave', function() { this.value = false }.bind(this))
			} else {
				this._hmHoverBinder.on('mouseover', function() { this.value = true }.bind(this))
				this._hmHoverBinder.on('mouseout', function() { this.value = false }.bind(this))
			}
		}
		if (this._hmHoverBinder)
			this._hmHoverBinder.enable(value)
	}

	///@private
	onEnabledChanged: { this._bindHover(value) }
}

Add 'hovered' property to the parent

/// this mixin provides mouse hover events handling
BaseMouseMixin {
	property bool value;			///< is 'true' if item if hovered, 'false' otherwise

	///@private
	constructor: {
		this.element = this.parent.element;
		this.parent.style('cursor', this.cursor)
		this._bindHover(this.enabled)
		exports.addProperty(parent, "bool", "hovered", false)
	}

	///@private
	function _bindHover(value) {
		if (value && !this._hmHoverBinder) {
			this._hmHoverBinder = new $core.EventBinder(this.parent.element)

			if (this._context.backend.capabilities.mouseEnterLeaveSupported) {
				this._hmHoverBinder.on('mouseenter', function() { this.value = true }.bind(this))
				this._hmHoverBinder.on('mouseleave', function() { this.value = false }.bind(this))
			} else {
				this._hmHoverBinder.on('mouseover', function() { this.value = true }.bind(this))
				this._hmHoverBinder.on('mouseout', function() { this.value = false }.bind(this))
			}
		}
		if (this._hmHoverBinder)
			this._hmHoverBinder.enable(value)
	}

	onValueChanged: { this.parent.hovered = value }
	onEnabledChanged: { this._bindHover(value) }
}