import QtQuick 2.4
import QtQuick.Dialogs 1.0

import QmlToolbox.Base 1.0
import QmlToolbox.Controls 1.0

/**
*  EditorFilename
*
*  Editor for properties of type 'filename'
*/
Editor
{
    id: item

    implicitWidth:  input.implicitWidth
    implicitHeight: input.implicitHeight

    TextField
    {
        id: input

        anchors.top:         parent.top
        anchors.bottom:      parent.bottom
        anchors.left:        parent.left
        anchors.right:       button.left
        anchors.rightMargin: Ui.style.paddingMedium

        readOnly: true

        onEditingFinished:
        {
            item.properties.setValue(item.path, item.slot, text);
        }
    }

    Button
    {
        id: button

        anchors.top:    parent.top
        anchors.bottom: parent.bottom
        anchors.right:  parent.right
        implicitWidth:  32

        text: '...'

        onClicked:
        {
            fileDialog.open();
        }
    }

    FileDialog
    {
        id: fileDialog

        title:          'Open texture'
        selectExisting: true
        selectFolder:   false
        selectMultiple: false

        onAccepted:
        {
            var path = QmlUtils.urlToLocalFile(fileUrl);

            input.text = path;
            item.properties.setValue(item.path, item.slot, path);
        }
    }

    onStatusChanged:
    {
        input.text = status.value;
    }
}

Add option to specify the default folder for the file dialog

import QtQuick 2.4
import QtQuick.Dialogs 1.0

import QmlToolbox.Base 1.0
import QmlToolbox.Controls 1.0

/**
*  EditorFilename
*
*  Editor for properties of type 'filename'
*/
Editor
{
    id: item

    implicitWidth:  input.implicitWidth
    implicitHeight: input.implicitHeight

    TextField
    {
        id: input

        anchors.top:         parent.top
        anchors.bottom:      parent.bottom
        anchors.left:        parent.left
        anchors.right:       button.left
        anchors.rightMargin: Ui.style.paddingMedium

        readOnly: true

        onEditingFinished:
        {
            item.properties.setValue(item.path, item.slot, text);
        }
    }

    Button
    {
        id: button

        anchors.top:    parent.top
        anchors.bottom: parent.bottom
        anchors.right:  parent.right
        implicitWidth:  32

        text: '...'

        onClicked:
        {
            fileDialog.open();
        }
    }

    FileDialog
    {
        id: fileDialog

        title:          'Open texture'
        selectExisting: true
        selectFolder:   false
        selectMultiple: false

        onAccepted:
        {
            var path = QmlUtils.urlToLocalFile(fileUrl);

            input.text = path;
            item.properties.setValue(item.path, item.slot, path);
        }
    }

    onStatusChanged:
    {
        input.text = status.value;

        if (status.hasOwnProperty('folder')) {
            fileDialog.folder = status.folder;
        }
    }
}


import qbs 1.0
import '../QtModule.qbs' as QtModule

QtModule {
    condition: qt.core.versionMajor >= 5
    Depends { name: "qt.webkit" }
    Depends { name: "qt.gui" }
    qtModuleName: 'WebKitWidgets'
    repository: 'qtwebkit'
}


ListView {
	id: options;
	//TODO: use contentWidth instead!
	width: 335;
	height: parent.height;
	anchors.right: parent.right;
	anchors.bottom: parent.bottom;
	orientation: ListView.Horizontal;
	spacing: 25;
	model: optionsModel;
	delegate: Item {
		width: icon.paintedWidth + optionText.paintedWidth * 2; //TODO: image width isn't working
		height: parent.height;

		Image {
			id: icon;
			source: model.source;
			anchors.left: parent.left;
			anchors.verticalCenter: parent.verticalCenter;
		}

		Text {
			id: optionText;
			anchors.left: icon.right;
			anchors.leftMargin: 10;
			anchors.verticalCenter: parent.verticalCenter;
			color: "#fff";
			text: model.text;
		}
	}
}

Remove default model for options. Fix build.

ListView {
	id: options;
	//TODO: use contentWidth instead!
	width: 335;
	height: parent.height;
	anchors.right: parent.right;
	anchors.bottom: parent.bottom;
	orientation: ListView.Horizontal;
	spacing: 25;
	delegate: Item {
		width: icon.paintedWidth + optionText.paintedWidth * 2; //TODO: image width isn't working
		height: parent.height;

		Image {
			id: icon;
			source: model.source;
			anchors.left: parent.left;
			anchors.verticalCenter: parent.verticalCenter;
		}

		Text {
			id: optionText;
			anchors.left: icon.right;
			anchors.leftMargin: 10;
			anchors.verticalCenter: parent.verticalCenter;
			color: "#fff";
			text: model.text;
		}
	}
}


import QtQuick 2.3
import MarbleItem 1.0

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

    MarbleItem
    {
        anchors.fill: parent
        id: marbleMaps
        visible: true
        focus: true
    }
}

Set default theme and plugins visibility for Marble Maps app.

import QtQuick 2.3
import MarbleItem 1.0

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

    MarbleItem
    {
        id: marbleMaps

        anchors.fill: parent
        visible: true
        focus: true

        // Theme settings.
        projection: MarbleItem.Mercator
        mapThemeId: "earth/openstreetmap/openstreetmap.dgml"

        // Visibility of layers/plugins.
        showFrameRate: false
        showAtmosphere: false
        showCompass: false
        showClouds: false
        showCrosshairs: false
        showGrid: false
        showOverviewMap: false
        showOtherPlaces: false
        showScaleBar: false
        showBackground: false
    }
}


import QtQuick 2.0

BasicModellerObject {

    nameText: "Connector"

    property int defaultWidth : 100
    property int defaultHeight : 5

    width: defaultWidth
    height: defaultHeight

    property var endX
    property var endY

    function isSelected(checkX, checkY) {
        selected = checkX > x && checkX < (x + width) && checkY > y && checkY < (y + height)
        return selected;
    }

    function draw(ctx) {
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(x, y);
        endX = x + width;
        endY = y;
         if (selected) {
             ctx.lineWidth = 2
             ctx.strokeStyle = "red"
             ctx.lineTo(x + width, y);
         } else {
             ctx.lineTo(x + width, y);
         }
         if (endX > x) {
             // draw arrow to the right
         } else {
             // draw arrow to the left
         }

        ctx.stroke();
        ctx.restore();
    }
}

Use xy as center coordinates of the drawn object

import QtQuick 2.0

BasicModellerObject {

    nameText: "Connector"

    property int defaultWidth : 100
    property int defaultHeight : 5

    width: defaultWidth
    height: defaultHeight

    property var endX
    property var endY

//    function isSelected(checkX, checkY) {
//        selected = checkX > (x - width) && checkX < (x + width) && checkY > (y - height) && checkY < (y + height)
//        return selected;
//    }

    function draw(ctx) {
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(x-width/2, y);
        endX = x + width;
        endY = y;
         if (selected) {
             ctx.lineWidth = 2
             ctx.strokeStyle = "red"
             ctx.lineTo(x + width/2, y);
         } else {
             ctx.lineTo(x + width/2, y);
         }
         if (endX > x) {
             // draw arrow to the right
         } else {
             // draw arrow to the left
         }

        ctx.stroke();
        ctx.restore();
    }
}


/****************************************************************************
**
** Copyright (c) 2014 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jolla.com>
** Contact: Raine Makelelainen <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.0
import Sailfish.Silica 1.0

Image {
    property string icon

    sourceSize.width: Theme.iconSizeLauncher
    sourceSize.height: Theme.iconSizeLauncher
    width: Theme.iconSizeLauncher
    height: Theme.iconSizeLauncher

    source: {
        if (icon.indexOf(':/') !== -1 || icon.indexOf("data:image/png;base64") === 0) {
            return icon
        } else if (icon.indexOf('/') === 0) {
            return 'file://' + icon
        } else {
            return 'image://theme/' + icon
        }
    }

    onStatusChanged: {
        if (status === Image.Error) {
            icon = "icon-launcher-bookmark"
        }
    }
}

Revert to default icon faster if FavouriteIcon name is empty

/****************************************************************************
**
** Copyright (c) 2014 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jolla.com>
** Contact: Raine Makelelainen <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.0
import Sailfish.Silica 1.0

Image {
    property string icon

    sourceSize.width: Theme.iconSizeLauncher
    sourceSize.height: Theme.iconSizeLauncher
    width: Theme.iconSizeLauncher
    height: Theme.iconSizeLauncher

    source: {
        if (!icon.length) {
            return "image://theme/icon-launcher-bookmark"
        } else if (icon.indexOf(':/') !== -1 || icon.indexOf("data:image/png;base64") === 0) {
            return icon
        } else if (icon.indexOf('/') === 0) {
            return 'file://' + icon
        } else {
            return 'image://theme/' + icon
        }
    }

    onStatusChanged: {
        if (status === Image.Error) {
            icon = "icon-launcher-bookmark"
        }
    }
}


import QtQuick 2.0
import QtTest 1.0
import Shell 1.0
import Spark.js.redux 1.0
import Spark.js.qtredux 1.0
import Spark.js.immutabilityhelper 1.0
import Spark.actions 1.0
import Spark.reducers 1.0
import Spark.actions 1.0

Item {

    function logger(log) {
        return function () {
            return function(next) {
                return function(action) {
                    log.push(action.type);
                    next(action);
                }
            }
        }
    }

    TestCase {
        name: "Middleware"

        Item {
            id: mockDialog
            property bool selectMultiple
            property bool selectExisting
            property var nameFilters
            property string folder

            function open() {
            }
        }

        Item {
            id: mockSettings
            property string saveFolder: "";
        }

        function test_CopyToFileMiddleware() {
            var log = [];
            function reducer(state, action) {
                if (state === undefined) {
                    return {
                        source: "file:///Main.qml",
                        fileName: "Main.qml",
                        selectedState: "Test"
                    }
                }
                return state;
            }
            var middlewares = Redux.applyMiddleware(logger(log),
                                                    CopyToFileMiddleware.create(mockDialog, mockSettings));
            var store = Redux.createStore(reducer,middlewares);

            store.dispatch({type: "askToSaveFile"});
            compare(log.length, 1);
            compare(mockDialog.folder, "file://Main(Test).png");
        }
    }
}

Clean up the warning message in Middleware::test_CopyToFileMiddleware test

import QtQuick 2.0
import QtTest 1.0
import Shell 1.0
import Spark.js.redux 1.0
import Spark.js.qtredux 1.0
import Spark.js.immutabilityhelper 1.0
import Spark.actions 1.0
import Spark.reducers 1.0
import Spark.actions 1.0

Item {

    function logger(log) {
        return function () {
            return function(next) {
                return function(action) {
                    log.push(action.type);
                    next(action);
                }
            }
        }
    }

    TestCase {
        name: "Middleware"

        Item {
            id: mockDialog
            property bool selectMultiple
            property bool selectExisting
            property var nameFilters
            property string folder

            signal accepted
            signal rejected

            function open() {
            }
        }

        Item {
            id: mockSettings
            property string saveFolder: "";
        }

        function test_CopyToFileMiddleware() {
            var log = [];
            function reducer(state, action) {
                if (state === undefined) {
                    return {
                        source: "file:///Main.qml",
                        fileName: "Main.qml",
                        selectedState: "Test"
                    }
                }
                return state;
            }
            var middlewares = Redux.applyMiddleware(logger(log),
                                                    CopyToFileMiddleware.create(mockDialog, mockSettings));
            var store = Redux.createStore(reducer,middlewares);

            store.dispatch({type: "askToSaveFile"});
            compare(log.length, 1);
            compare(mockDialog.folder, "file://Main(Test).png");
        }
    }
}


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

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

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

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

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

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

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

Check if activity stack is empty

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

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

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

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

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

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

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

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


import qbs
import "../../version.js" as Version

Product {
    Depends { name: "cpp" }
    Depends { name: "Qt"; submodules: ["core"] }
    version: Version.qbsVersion()
    type: Qt.core.staticBuild ? "staticlibrary" : "dynamiclibrary"
    targetName: (qbs.enableDebugCode && qbs.targetOS.contains("windows")) ? (name + 'd') : name
    destinationDirectory: qbs.targetOS.contains("windows") ? "bin" : project.libDirName
    cpp.defines: base.concat(type == "staticlibrary" ? ["QBS_STATIC_LIB"] : ["QBS_LIBRARY"])
    cpp.installNamePrefix: "@rpath/"
    property string headerInstallPrefix: "/include/qbs"
    Group {
        fileTagsFilter: product.type.concat("dynamiclibrary_symlink")
        qbs.install: true
        qbs.installDir: project.libInstallDir
    }
    Export {
        Depends { name: "cpp" }
        Depends { name: "Qt"; submodules: ["core"] }
        cpp.rpaths: project.libRPaths
        cpp.includePaths: "."
        cpp.defines: product.type === "staticlibrary" ? ["QBS_STATIC_LIB"] : []
    }
}

Switch on symbol hiding in qbs project file.

import qbs
import "../../version.js" as Version

Product {
    Depends { name: "cpp" }
    Depends { name: "Qt"; submodules: ["core"] }
    version: Version.qbsVersion()
    type: Qt.core.staticBuild ? "staticlibrary" : "dynamiclibrary"
    targetName: (qbs.enableDebugCode && qbs.targetOS.contains("windows")) ? (name + 'd') : name
    destinationDirectory: qbs.targetOS.contains("windows") ? "bin" : project.libDirName
    cpp.defines: base.concat(type == "staticlibrary" ? ["QBS_STATIC_LIB"] : ["QBS_LIBRARY"])
    cpp.installNamePrefix: "@rpath/"
    cpp.visibility: "minimal"
    property string headerInstallPrefix: "/include/qbs"
    Group {
        fileTagsFilter: product.type.concat("dynamiclibrary_symlink")
        qbs.install: true
        qbs.installDir: project.libInstallDir
    }
    Export {
        Depends { name: "cpp" }
        Depends { name: "Qt"; submodules: ["core"] }
        cpp.rpaths: project.libRPaths
        cpp.includePaths: "."
        cpp.defines: product.type === "staticlibrary" ? ["QBS_STATIC_LIB"] : []
    }
}


import qbs

CppApplication {
    name: "the app"
    consoleApplication: true

    cpp.separateDebugInformation: false
    Properties {
        condition: qbs.targetOS.contains("macos")
        bundle.embedInfoPlist: false
    }

    files: "main.cpp"
    qbs.installPrefix: "/usr/local"
    Group {
        fileTagsFilter: "application"
        qbs.install: true
        qbs.installDir: "bin"
    }
}

Fix TestBlackbox::makefileGenerator on macOS again

import qbs

CppApplication {
    name: "the app"
    consoleApplication: true

    cpp.cxxLanguageVersion: "c++11"
    cpp.separateDebugInformation: false
    Properties {
        condition: qbs.targetOS.contains("macos")
        bundle.embedInfoPlist: false
        cpp.minimumMacosVersion: "10.7"
    }

    files: "main.cpp"
    qbs.installPrefix: "/usr/local"
    Group {
        fileTagsFilter: "application"
        qbs.install: true
        qbs.installDir: "bin"
    }
}


import QtQuick 1.0
import "custom" as Components
import "plugin"

Components.ChoiceList {
    id:choicelist

    property int buttonHeight: buttonitem.sizeFromContents(100, 18).height
    QStyleItem { id:buttonitem; elementType:"combobox" }
    height: buttonHeight
    topMargin:4
    bottomMargin:4

    QStyleItem {
        id:styleitem
        elementType: "combobox"
        sunken: pressed
        raised: !pressed
        hover: containsMouse
        enabled:choicelist.enabled
    }

    background: QStyleBackground {
        anchors.fill:parent
        style: styleitem
    }

    listItem: Item {
        id:item

        height:22
        anchors.left:parent.left
        width:choicelist.width
        QStyleBackground {
            anchors.fill:parent
            style: QStyleItem {
                elementType: "menuitem"
                text: choicelist.model.get(index).text
                selected: highlighted
            }
        }
    }

    popupFrame: QStyleBackground {
        property string behavior: styleitem.styleHint("comboboxpopup") ? "MacOS" : "Windows"
        onBehaviorChanged:print(behavior) + styleitem.styleHint("comboboxpopup")
        property int fw: styleitem.pixelMetric("menupanelwidth");
        anchors.leftMargin: styleitem.pixelMetric("menuhmargin") + fw
        anchors.rightMargin: styleitem.pixelMetric("menuhmargin") + fw
        anchors.topMargin: styleitem.pixelMetric("menuvmargin") + fw
        anchors.bottomMargin: styleitem.pixelMetric("menuvmargin") + fw
        style:QStyleItem{elementType:"menu"}
    }
}

Remove some debug from choicelist

import QtQuick 1.0
import "custom" as Components
import "plugin"

Components.ChoiceList {
    id:choicelist

    property int buttonHeight: buttonitem.sizeFromContents(100, 18).height
    QStyleItem { id:buttonitem; elementType:"combobox" }
    height: buttonHeight
    topMargin:4
    bottomMargin:4

    QStyleItem {
        id:styleitem
        elementType: "combobox"
        sunken: pressed
        raised: !pressed
        hover: containsMouse
        enabled:choicelist.enabled
    }

    background: QStyleBackground {
        anchors.fill:parent
        style: styleitem
    }

    listItem: Item {
        id:item

        height:22
        anchors.left:parent.left
        width:choicelist.width
        QStyleBackground {
            anchors.fill:parent
            style: QStyleItem {
                elementType: "menuitem"
                text: choicelist.model.get(index).text
                selected: highlighted
            }
        }
    }

    popupFrame: QStyleBackground {
        property string behavior: styleitem.styleHint("comboboxpopup") ? "MacOS" : "Windows"
        property int fw: styleitem.pixelMetric("menupanelwidth");
        anchors.leftMargin: styleitem.pixelMetric("menuhmargin") + fw
        anchors.rightMargin: styleitem.pixelMetric("menuhmargin") + fw
        anchors.topMargin: styleitem.pixelMetric("menuvmargin") + fw
        anchors.bottomMargin: styleitem.pixelMetric("menuvmargin") + fw
        style:QStyleItem{elementType:"menu"}
    }
}


import QtQuick 2.0
import Sailfish.Silica 1.0

Page{
    id: settingsPage
    SilicaFlickable {
        anchors.fill: parent

        // Tell SilicaFlickable the height of its content.
        contentHeight: column.height

        // Place our content in a Column.  The PageHeader is always placed at the top
        // of the page, followed by our content.
        Column {
            id: column

            width: settingsPage.width
            spacing: Theme.paddingLarge

            PageHeader {
                title: qsTr("Settings")
            }
        }
        PullDownMenu {
            MenuItem{
                text:qsTr("Help")
                onClicked: pageStack.push(Qt.resolvedUrl("Help.qml"))
            }

            MenuItem{
                text: qsTr("About")
                onClicked: pageStack.push(Qt.resolvedUrl("About.qml"))
            }
        }
    }
}

Hide help page for the moment

import QtQuick 2.0
import Sailfish.Silica 1.0

Page{
    id: settingsPage
    SilicaFlickable {
        anchors.fill: parent

        contentHeight: column.height

        Column {
            id: column

            width: settingsPage.width
            spacing: Theme.paddingLarge

            PageHeader {
                title: qsTr("Settings")
            }
        }

        PullDownMenu {
//            MenuItem{
//                text:qsTr("Help")
//                onClicked: pageStack.push(Qt.resolvedUrl("Help.qml"))
//            }

            MenuItem{
                text: qsTr("About")
                onClicked: pageStack.push(Qt.resolvedUrl("About.qml"))
            }
        }
    }
}


import QtQuick 2.0
import ".."

View {
    id: listItem
    anchors {
        left: parent.left
        right: parent.right
    }

    property int margins: units.dp(16)

    property bool selected

    property int dividerInset: 0
    property bool showDivider: false

    signal triggered()

    ThinDivider {
        anchors.bottom: parent.bottom
        anchors.leftMargin: dividerInset

        visible: showDivider
    }

    Ink {
        id: ink
        onClicked: listItem.triggered()
        anchors.fill: parent
    }

    tintColor: selected ? Qt.rgba(0,0,0,0.07) : ink.containsMouse ? Qt.rgba(0,0,0,0.03) : Qt.rgba(0,0,0,0)
}

Fix issue with checkbox not toggling in a list item

import QtQuick 2.0
import ".."

View {
    id: listItem
    anchors {
        left: parent.left
        right: parent.right
    }

    property int margins: units.dp(16)

    property bool selected

    property int dividerInset: 0
    property bool showDivider: false

    signal triggered()

    ThinDivider {
        anchors.bottom: parent.bottom
        anchors.leftMargin: dividerInset

        visible: showDivider
    }

    Ink {
        id: ink
        onClicked: listItem.triggered()
        anchors.fill: parent
        z: -1
    }

    tintColor: selected ? Qt.rgba(0,0,0,0.07) : ink.containsMouse ? Qt.rgba(0,0,0,0.03) : Qt.rgba(0,0,0,0)
}


import QtQuick 2.1
import QtQuick.Controls 1.2

Item {
  Component {
    id: cameraPositionNameDelegate

    Item {
      TextInput {
        anchors.fill: parent
        text: styleData.value
        onTextChanged: {
          if (cameraPositions) cameraPositions.changeName(styleData.row, text);
        }
      }
    }
  }

  Column {
    x: 70; y: 20
    width: 430
    height: 170

    TableView {
      id: cameraPositionsTableView
      TableViewColumn {
        role: "name"
        title: "Name"
        width: 150
        delegate: cameraPositionNameDelegate
      }
      width: 417
      height: 190
      model: cameraPositions
      focus: true
      clip: true
    }

    Row {
      spacing: 10
      Button {
        text: "Save position"
        onClicked: {
          if (cameraPositions) cameraPositions.save();
        }
      }
      Button {
        text: "Delete position"
        onClicked: {
          if (cameraPositions) cameraPositions.deletePosition(cameraPositionsTableView.currentRow);
        }
      }
    }
  }
}

Adjust position and size of camera positions table.

import QtQuick 2.1
import QtQuick.Controls 1.2

Item {
  Component {
    id: cameraPositionNameDelegate

    Item {
      TextInput {
        anchors.fill: parent
        text: styleData.value
        onTextChanged: {
          if (cameraPositions) cameraPositions.changeName(styleData.row, text);
        }
      }
    }
  }

  Column {
    x: 570; y: 250
    width: 430
    height: 170

    TableView {
      id: cameraPositionsTableView
      TableViewColumn {
        role: "name"
        title: "Name"
        width: 380
        delegate: cameraPositionNameDelegate
      }
      width: 400
      height: 190
      model: cameraPositions
      focus: true
      clip: true
    }

    Row {
      spacing: 10
      Button {
        text: "Save position"
        onClicked: {
          if (cameraPositions) cameraPositions.save();
        }
      }
      Button {
        text: "Delete position"
        onClicked: {
          if (cameraPositions) cameraPositions.deletePosition(cameraPositionsTableView.currentRow);
        }
      }
    }
  }
}


import qbs.base 1.0
import qbs.fileinfo 1.0 as FileInfo

Module {
    property string buildVariant: "debug"
    property bool enableDebugCode: buildVariant == "debug"
    property bool debugInformation: (buildVariant == "debug")
    property string optimization: (buildVariant == "debug" ? "none" : "fast")
    property string hostOS: getHostOS()
    property string pathListSeparator: hostOS === "windows" ? ";" : ":"
    property string pathSeparator: hostOS === "windows" ? "\\" : "/"
    property string targetOS: hostOS
    property var targetPlatform: {
        if (targetOS === "linux")
            return [ "unix", "linux" ];
        else if (targetOS === "android")
            return [ "unix", "android" ];
        else if (targetOS === "mac")
            return [ "unix", "darwin", "mac" ];
        else if (targetOS === "windows")
            return [ "windows" ];
        else
            throw "Unknown targetOS: \"" + targetOS + "\""
    }
    property string profile
    property string toolchain
    property string architecture
    property string endianness
    property bool install: false
    property string installDir
    property string sysroot

    PropertyOptions {
        name: "buildVariant"
        allowedValues: ['debug', 'release']
        description: "name of the build variant"
    }

    PropertyOptions {
        name: "optimization"
        allowedValues: ['none', 'fast', 'small']
        description: "optimization level"
    }
}

Make the qbs.platforms property a bit more generic.

import qbs.base 1.0
import qbs.fileinfo 1.0 as FileInfo

Module {
    property string buildVariant: "debug"
    property bool enableDebugCode: buildVariant == "debug"
    property bool debugInformation: (buildVariant == "debug")
    property string optimization: (buildVariant == "debug" ? "none" : "fast")
    property string hostOS: getHostOS()
    property string pathListSeparator: hostOS === "windows" ? ";" : ":"
    property string pathSeparator: hostOS === "windows" ? "\\" : "/"
    property string targetOS: hostOS
    property var targetPlatform: {
        var platforms = [targetOS];
        if (targetOS === "linux")
            platforms.push("unix");
        else if (targetOS === "android")
            platforms.push("linux", "unix");
        else if (targetOS === "mac")
            platforms.push("darwin", "unix");
        return platforms
    }
    property string profile
    property string toolchain
    property string architecture
    property string endianness
    property bool install: false
    property string installDir
    property string sysroot

    PropertyOptions {
        name: "buildVariant"
        allowedValues: ['debug', 'release']
        description: "name of the build variant"
    }

    PropertyOptions {
        name: "optimization"
        allowedValues: ['none', 'fast', 'small']
        description: "optimization level"
    }
}


import QtQuick 2.0
import QtQuick.Dialogs 1.0

import QmlToolbox.Base 1.0
import QmlToolbox.Controls 1.0
import QmlToolbox.PipelineEditor 1.0

BaseItem
{
    id: item

    property var    pipelineInterface: null ///< Interface for communicating with the actual pipeline
    property string path:              ''   ///< Path to pipeline slot (e.g., 'pipeline.Stage1.in1')

    implicitWidth:  150
    implicitHeight: 25

    Rectangle
    {
        id: input

        anchors.fill: parent

        color: '#000000'

        MouseArea
        {
            anchors.fill: parent

            onClicked:
            {
                colorDialog.color = input.color;
                colorDialog.open();
            }
        }
    }

    ColorDialog
    {
        id: colorDialog

        onAccepted:
        {
            input.color = color;

            pipelineInterface.setSlotValue(path, color);
        }
    }

    function update()
    {
        var slotInfo = pipelineInterface.getSlot(path);
        input.color = slotInfo.value;
    }
}

Fix color editor (pass string instead of qml color type)

import QtQuick 2.0
import QtQuick.Dialogs 1.0

import QmlToolbox.Base 1.0
import QmlToolbox.Controls 1.0
import QmlToolbox.PipelineEditor 1.0

BaseItem
{
    id: item

    property var    pipelineInterface: null ///< Interface for communicating with the actual pipeline
    property string path:              ''   ///< Path to pipeline slot (e.g., 'pipeline.Stage1.in1')

    implicitWidth:  150
    implicitHeight: 25

    Rectangle
    {
        id: input

        anchors.fill: parent

        color: '#000000'

        MouseArea
        {
            anchors.fill: parent

            onClicked:
            {
                colorDialog.color = input.color;
                colorDialog.open();
            }
        }
    }

    ColorDialog
    {
        id: colorDialog

        onAccepted:
        {
            input.color = color;

            pipelineInterface.setSlotValue(path, color.toString());
        }
    }

    function update()
    {
        var slotInfo = pipelineInterface.getSlot(path);
        input.color = slotInfo.value;
    }
}


import Qt 4.7

Rectangle {
    id: root

    MainView {
        id: mainView
        width: parent.width
        height: parent.height
        onLogoClicked: {
            root.state = "about"
        }
    }

    About {
        id: aboutView
        width: parent.width
        height: parent.height
        anchors.left: mainView.right
        z: 100
        onExit: {
            root.state = "search"
        }
    }

    function settingsSaved(filename) {
        console.log("Settings saved to " + filename)
    }

    states: [
        State {
            name: "search"
        },
        State {
            name: "about"
            PropertyChanges {
                target: mainView
                x: -mainView.width
            }
        }
    ]

    transitions: Transition {
        from: "*"
        to: "*"
        NumberAnimation {
            properties: "x";
            easing.type: Easing.InOutQuad
            duration: 300
        }
    }
}

Remove obsolete z from aboutView, no longer necessary

import Qt 4.7

Rectangle {
    id: root

    MainView {
        id: mainView
        width: parent.width
        height: parent.height
        onLogoClicked: {
            root.state = "about"
        }
    }

    About {
        id: aboutView
        width: parent.width
        height: parent.height
        anchors.left: mainView.right
        onExit: {
            root.state = "search"
        }
    }

    function settingsSaved(filename) {
        console.log("Settings saved to " + filename)
    }

    states: [
        State {
            name: "search"
        },
        State {
            name: "about"
            PropertyChanges {
                target: mainView
                x: -mainView.width
            }
        }
    ]

    transitions: Transition {
        from: "*"
        to: "*"
        NumberAnimation {
            properties: "x";
            easing.type: Easing.InOutQuad
            duration: 300
        }
    }
}


Implement Slider input (input type 'range').

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


import QtQuick 2.8
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import org.kde.kirigami 2.8 as Kirigami

RowLayout {
    property bool showButton: true
    property bool showSlider: true
    property bool showLabel: true
    spacing: 1

    CheckButton {
        icon.name: mute ? "player-volume-muted" : "player-volume"
        visible: showButton
        flat: true
        onClicked: player.setMute(!mute)
        checked: mute

        ToolTip.text: mute ?  'Volume is muted' : 'Mute'
        ToolTip.visible: hovered
        ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
    }
    Slider {
        id: control
        visible: showSlider
        padding: 0
        value: volume
        Layout.fillWidth: true

        onMoved: player.setVolume(value)

        ToolTip {
            visible: showLabel && control.pressed
            text: Math.round(control.value*100) + '%'
            delay: 0
        }
    }
}

Use different icons for mute/muted

import QtQuick 2.8
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import org.kde.kirigami 2.8 as Kirigami

RowLayout {
    property bool showButton: true
    property bool showSlider: true
    property bool showLabel: true
    spacing: 1

    CheckButton {
        icon.name: mute ? "volume-level-muted" : "volume-level-high"
        visible: showButton
        flat: true
        onClicked: player.setMute(!mute)
        checked: mute

        ToolTip.text: mute ?  'Volume is muted' : 'Mute'
        ToolTip.visible: hovered
        ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
    }
    Slider {
        id: control
        visible: showSlider
        padding: 0
        value: volume
        Layout.fillWidth: true

        onMoved: player.setVolume(value)

        ToolTip {
            visible: showLabel && control.pressed
            text: Math.round(control.value*100) + '%'
            delay: 0
        }
    }
}


/****************************************************************************
**
** Copyright (C) 2015 Jolla Ltd.
** 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
import Sailfish.Silica.private 1.0 as Private
import "." as Browser

Rectangle {
    color: "black"
    opacity: 0.7

    Private.Wallpaper {
        anchors.fill: parent
        source: ""
        glassOnly: true
        effect.blending: true
    }
}

Make background a bit darker

/****************************************************************************
**
** Copyright (C) 2015 Jolla Ltd.
** 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
import Sailfish.Silica.private 1.0 as Private
import "." as Browser

Rectangle {
    color: "black"
    opacity: 0.8

    Private.Wallpaper {
        anchors.fill: parent
        source: ""
        glassOnly: true
        effect.blending: true
    }
}


///simple activity control
BaseActivity {
	property bool handleDisplay;	///< use this flag if you want to hide inactive activivties with CSS 'display' property.

	///start activity
	start: {
		if (this.handleDisplay)
			this.style('display', 'block')
		this.visible = true
		this.started()
	}

	///stop activity
	stop: {
		if (this.handleDisplay)
			this.style('display', 'none')
		this.visible = false
		this.stopped()
	}

	///get activity item
	function getActivity() {
		return this
	}
}

Remove 'display' style toggling from activity

///simple activity control
BaseActivity {
	///start activity
	start: {
		this.visible = true
		this.started()
	}

	///stop activity
	stop: {
		this.visible = false
		this.stopped()
	}

	///get activity item
	function getActivity() {
		return this
	}
}


import qbs

Project {
    property string windowsProfile: "windowsProfile"
    property bool enableProfiles
    property stringList mingwToolchain: ["mingw", "gcc"]
    Profile {
        name: windowsProfile
        qbs.targetOS: ["windows"]
    }

    Profile {
        name: "mingwProfile"
        condition: enableProfiles
        baseProfile: project.windowsProfile
        qbs.toolchain: project.mingwToolchain
    }

    Application {
        name: "app"
        Depends { name: "cpp"; required: false }
        multiplexByQbsProperties: ["buildVariants", "profiles"]
        qbs.buildVariants: ["debug", "release"]
        qbs.profiles: ["mingwProfile"]
    }
    DynamicLibrary {
        name: "lib"

        Depends { name: "cpp"; required: false }

        property stringList clangToolchain: ["clang", "llvm", "gcc"]
        property string clangProfileName: "clangProfile"

        Profile {
            name: product.clangProfileName
            condition: project.enableProfiles
            qbs.targetOS: ["linux", "unix"]
            qbs.toolchain: product.clangToolchain
        }

        multiplexByQbsProperties: ["profiles"]
        qbs.profiles: ["mingwProfile", "clangProfile"]
    }
}

Fix "localProfiles" autotest on macOS

import qbs

Project {
    property string windowsProfile: "windowsProfile"
    property bool enableProfiles
    property stringList mingwToolchain: ["mingw", "gcc"]
    Profile {
        name: windowsProfile
        qbs.targetOS: ["windows"]
    }

    Profile {
        name: "mingwProfile"
        condition: enableProfiles
        baseProfile: project.windowsProfile
        qbs.toolchain: project.mingwToolchain
    }

    Application {
        name: "app"
        Depends { name: "cpp"; required: false }
        aggregate: false
        multiplexByQbsProperties: ["buildVariants", "profiles"]
        qbs.buildVariants: ["debug", "release"]
        qbs.profiles: ["mingwProfile"]
    }
    DynamicLibrary {
        name: "lib"

        Depends { name: "cpp"; required: false }

        property stringList clangToolchain: ["clang", "llvm", "gcc"]
        property string clangProfileName: "clangProfile"

        Profile {
            name: product.clangProfileName
            condition: project.enableProfiles
            qbs.targetOS: ["linux", "unix"]
            qbs.toolchain: product.clangToolchain
        }

        multiplexByQbsProperties: ["profiles"]
        qbs.profiles: ["mingwProfile", "clangProfile"]
    }
}


import QtQuick 2.3
import QtQuick.Window 2.2
import QtMultimedia 5.5
import QtQuick.Controls 1.4
import App.constants 1.0
import App.adapters 1.0
import App.actions 1.0
import App.stores 1.0

Window {
    id: mainWindow
    visible: false
    width: 480
    height: 640

    StoreAdapter {
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            AppActions.quitApp();
        }
    }

    Text {
        text: qsTr(MainStore.text)
        anchors.centerIn: parent
    }

}

Remove QtMultimedia from template code. Avoid to affect qmlimportscanner

import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import App.constants 1.0
import App.adapters 1.0
import App.actions 1.0
import App.stores 1.0

Window {
    id: mainWindow
    visible: false
    width: 480
    height: 640

    StoreAdapter {
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            AppActions.quitApp();
        }
    }

    Text {
        text: qsTr(MainStore.text)
        anchors.centerIn: parent
    }

}


import qbs

Project {
    StaticLibrary {
        name: "theLib"
        destinationDirectory: project.buildDirectory
        Depends { name: "cpp" }
        files: ["lib.cpp"]
    }
    CppApplication {
        name: "theApp"
        cpp.libraryPaths: project.buildDirectory
        files: ["main.cpp"]
        cpp.staticLibraries: ['@' + sourceDirectory + '/'
                + (qbs.toolchain.contains("msvc") ? "list.msvc" : "list.gcc")]
    }
}

Fix commandFile autotest on Mac

import qbs

Project {
    StaticLibrary {
        name: "theLib"
        destinationDirectory: project.buildDirectory
        Depends { name: "cpp" }
        bundle.isBundle: false
        files: ["lib.cpp"]
    }
    CppApplication {
        name: "theApp"
        cpp.libraryPaths: project.buildDirectory
        files: ["main.cpp"]
        cpp.staticLibraries: ['@' + sourceDirectory + '/'
                + (qbs.toolchain.contains("msvc") ? "list.msvc" : "list.gcc")]
    }
}


Object {
	property bool macAccessable: false;

	getDeviceId(callback): {
		var deviceString = this._context.system.os + "_" + this._context.system.browser
		deviceString = deviceString.replace(/\s/g, '')
		callback(deviceString)
	}

	getMacAddress(callback): { callback("") }
}

Add modelname stub in android device

Object {
	property bool macAccessable: false;
	property string modelName: "androidtv";

	getDeviceId(callback): {
		var deviceString = this._context.system.os + "_" + this._context.system.browser
		deviceString = deviceString.replace(/\s/g, '')
		callback(deviceString)
	}

	getMacAddress(callback): { callback("") }
}


// -*- qml -*-

/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

import QtQuick 2.0
import Sailfish.Silica 1.0

ApplicationWindow {
    property bool active: Qt.application.active
}

Remove the default SailfishOS cover

// -*- qml -*-

/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

import QtQuick 2.0
import Sailfish.Silica 1.0

ApplicationWindow {
    property bool active: Qt.application.active
    cover: undefined
}


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

ColumnLayout {
    property alias title: titleLabel.text;
    property alias contents: contentsItem.children;

    Label {
        id: titleLabel;
    }

    Item {
        id: contentsItem;
        Layout.fillWidth: true;
        Layout.fillHeight: true;
        clip: true;
    }
}

Update preferences page styling and add a reset() base method

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

import UM 1.0 as UM

ColumnLayout {
    property alias title: titleLabel.text;
    property alias contents: contentsItem.children;

    function reset()
    {
    }

    Label {
        id: titleLabel;

        Layout.fillWidth: true;

        font.pointSize: 18;
    }

    Item {
        id: contentsItem;
        Layout.fillWidth: true;
        Layout.fillHeight: true;
        clip: true;
    }
}


import qbs 1.0

Project {
    minimumQbsVersion: "1.6"
    qbsSearchPaths: ["qbs-resources"]
    property bool withCode: true
    property bool withDocumentation: true
    property bool withExamples: false
    property bool withTests: withCode
    property stringList autotestArguments: []
    property stringList autotestWrapper: []

    references: [
        "docker/docker.qbs",
        "share/share.qbs",
        "scripts/scripts.qbs",
    ]

    SubProject {
        filePath: "doc/doc.qbs"
        Properties {
            condition: parent.withDocumentation
        }
    }

    SubProject {
        filePath: "examples/examples.qbs"
        Properties {
            condition: parent.withExamples
        }
    }

    SubProject {
        filePath: "src/src.qbs"
        Properties {
            condition: parent.withCode
        }
    }

    SubProject {
        filePath: "tests/tests.qbs"
        Properties {
            condition: parent.withTests
        }
    }

    Product {
        name: "version"
        files: ["VERSION"]
    }

    Product {
        name: "qmake project files for qbs"
        files: ["**/*.pr[io]"]
    }
}

Add a new project property "withDocker" on the Qbs build

import qbs 1.0

Project {
    minimumQbsVersion: "1.6"
    qbsSearchPaths: ["qbs-resources"]
    property bool withCode: true
    property bool withDocker: true
    property bool withDocumentation: true
    property bool withExamples: false
    property bool withTests: withCode
    property stringList autotestArguments: []
    property stringList autotestWrapper: []

    references: [
        "share/share.qbs",
        "scripts/scripts.qbs",
    ]

    SubProject {
        filePath: "docker/docker.qbs"
        Properties {
            condition: parent.withDocker
        }
    }

    SubProject {
        filePath: "doc/doc.qbs"
        Properties {
            condition: parent.withDocumentation
        }
    }

    SubProject {
        filePath: "examples/examples.qbs"
        Properties {
            condition: parent.withExamples
        }
    }

    SubProject {
        filePath: "src/src.qbs"
        Properties {
            condition: parent.withCode
        }
    }

    SubProject {
        filePath: "tests/tests.qbs"
        Properties {
            condition: parent.withTests
        }
    }

    Product {
        name: "version"
        files: ["VERSION"]
    }

    Product {
        name: "qmake project files for qbs"
        files: ["**/*.pr[io]"]
    }
}


import QtQuick 1.1

Slide {
    SemiboldText {
        id: text1
        x: 429
        y: 160
        color: "#ed7e15"
        text: qsTr("Luca Ottaviano")
        font.pointSize: 18
    }

    SemiboldText {
        id: text2
        x: 429
        y: 412
        color: "#3f579f"
        text: qsTr("Qt Quick")
        font.pointSize: 24
    }

    SemiboldText {
        id: text3
        x: 429
        y: 453
        width: 474
        height: 28
        color: "#3f579f"
        text: qsTr("Rapid application development in ambiente embedded")
        wrapMode: Text.WordWrap
        font.pointSize: 24
    }

    SemiboldText {
        id: text4
        x: 429
        y: 613
        color: "#646464"
        text: qsTr("Firenze - 25 Settembre 2012")
        font.pointSize: 18
    }
}

Make author's name in first page bigger.

import QtQuick 1.1

Slide {
    SemiboldText {
        id: text1
        x: 429
        y: 160
        color: "#ed7e15"
        text: qsTr("Luca Ottaviano")
        font.pointSize: 24
    }

    SemiboldText {
        id: text2
        x: 429
        y: 372
        color: "#3f579f"
        text: qsTr("Qt Quick")
        font.pointSize: 24
    }

    SemiboldText {
        id: text3
        x: 429
        y: 453
        width: 474
        height: 28
        color: "#3f579f"
        text: qsTr("Rapid application development in ambiente embedded")
        wrapMode: Text.WordWrap
        font.pointSize: 24
    }

    SemiboldText {
        id: text4
        x: 429
        y: 613
        color: "#646464"
        text: qsTr("Firenze - 25 Settembre 2012")
        font.pointSize: 18
    }
}


import QtQuick 2.0
import QtQml.Models 2.2

FocusScope {
    id: root
    property alias notemodel: delegate.model
    clip: true
    signal modelSelectionIndexChanged(int newIndex)
    signal modelSelectionDepthChanged(int newDepth)
    // These properties could eventually save themselves to disk, so as to have a non-default selection upon application start.
    property var mSelectedIndex: 0
    property var mSelectedDepth: 0

    VisualDataModel {
        id: delegate
        rootIndex: modelIndex(mSelectedDepth)
        delegate: Rectangle {
            id: drect
            height: 25
            width: parent.width
            Text {
                text: title
            }
        }
    }
    ListView {
        id: list
        anchors.fill: parent
        model: delegate
        currentIndex: 1
        highlightFollowsCurrentItem: true
        currentIndex: mSelectedIndex
        MouseArea {
            id: focusarea
            anchors.fill: parent
            onClicked: {
                mSelectedIndex = list.indexAt(mouse.x, mouse.y)
                modelSelectionChanged(mSelectedIndex)
            }
            onDoubleClicked: {
                mSelectedDepth = mSelectedDepth + 1
                modelSelectionDepthChanged(mSelectedDepth)
            }
        }
    }
}

Send initial state of "selections" upon application load.

import QtQuick 2.0
import QtQml.Models 2.2

FocusScope {
    id: root
    property alias notemodel: delegate.model
    clip: true
    signal modelSelectionIndexChanged(int newIndex)
    signal modelSelectionDepthChanged(int newDepth)
    // These properties could eventually save themselves to disk, so as to have a non-default selection upon application start.
    property var mSelectedIndex: 0
    property var mSelectedDepth: 0

    VisualDataModel {
        id: delegate
        rootIndex: modelIndex(mSelectedDepth)
        delegate: Rectangle {
            id: drect
            height: 25
            width: parent.width
            Text {
                text: title
            }
        }
    }
    ListView {
        id: list
        anchors.fill: parent
        model: delegate
        currentIndex: 1
        highlightFollowsCurrentItem: true
        currentIndex: mSelectedIndex
        Component.onCompleted: {
            modelSelectionDepthChanged(mSelectedDepth)
            modelSelectionIndexChanged(mSelectedIndex)
        }

        MouseArea {
            id: focusarea
            anchors.fill: parent
            onClicked: {
                mSelectedIndex = list.indexAt(mouse.x, mouse.y)
                modelSelectionChanged(mSelectedIndex)
            }
            onDoubleClicked: {
                mSelectedDepth = mSelectedDepth + 1
                modelSelectionDepthChanged(mSelectedDepth)
            }
        }
    }
}


import qbs
import QbsFunctions

Product {
    Depends { name: "Qt.core" }
    property string minimumQtVersion: "5.1.0"
    cpp.defines: ["QT_NO_CAST_FROM_ASCII", "QT_NO_PROCESS_COMBINED_ARGUMENT_START"]
    condition: QbsFunctions.versionIsAtLeast(Qt.core.version, minimumQtVersion)
}

Disable "insecure" warnings on qbs build with MSVC

import qbs
import QbsFunctions

Product {
    Depends { name: "Qt.core" }
    property string minimumQtVersion: "5.1.0"
    cpp.defines: {
        var res = ["QT_NO_CAST_FROM_ASCII", "QT_NO_PROCESS_COMBINED_ARGUMENT_START"];
        if (qbs.toolchain.contains("msvc"))
            res.push("_SCL_SECURE_NO_WARNINGS");
        return res;
    }
    condition: QbsFunctions.versionIsAtLeast(Qt.core.version, minimumQtVersion)
}


/****************************************************************************
**
** Copyright (C) 2014 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jolla.com>
** Contact: Raine Makelelainen <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.0
import Sailfish.Silica 1.0

Image {
    property string icon

    sourceSize.width: Theme.iconSizeLauncher
    sourceSize.height: Theme.iconSizeLauncher
    width: Theme.iconSizeLauncher
    height: Theme.iconSizeLauncher

    source: {
        if (icon.indexOf(':/') !== -1 || icon.indexOf("data:image/png;base64") === 0) {
            return icon
        } else if (icon.indexOf('/') === 0) {
            return 'file://' + icon
        } else {
            return 'image://theme/' + icon
        }
    }
}

Add error handling for favorite icons.

/****************************************************************************
**
** Copyright (C) 2014 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jolla.com>
** Contact: Raine Makelelainen <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.0
import Sailfish.Silica 1.0

Image {
    property string icon

    sourceSize.width: Theme.iconSizeLauncher
    sourceSize.height: Theme.iconSizeLauncher
    width: Theme.iconSizeLauncher
    height: Theme.iconSizeLauncher

    source: {
        if (icon.indexOf(':/') !== -1 || icon.indexOf("data:image/png;base64") === 0) {
            return icon
        } else if (icon.indexOf('/') === 0) {
            return 'file://' + icon
        } else {
            return 'image://theme/' + icon
        }
    }

    onStatusChanged: {
        if (status === Image.Error) {
            icon = "icon-launcher-bookmark"
        }
    }
}


/*******************************************************************************
 * Copyright 2012-2015 Esri
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 ******************************************************************************/

import QtPositioning 5.3
import QtQuick 2.3
import QtQuick.Controls 1.2
import ArcGIS.Runtime 10.26
import ArcGIS.Runtime.Toolkit.Controls 1.0

Rectangle {
    width: 500
    height: 400

    Map {
        id: mainMap
        anchors.fill: parent
        wrapAroundEnabled: true
        focus: true

        ArcGISTiledMapServiceLayer {
            url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
        }

        PositionSource {
            id: position
        }

        NavigationToolbar {
            id: navigationToolbar
            anchors {
                top: parent.top
                left: parent.left
                margins: 10
            }
        }

        onStatusChanged: {
            if (status === Enums.MapStatusReady) {
                mainMap.positionDisplay.positionSource = position;
            }
        }
    }
}

Add param to toolbar example

/*******************************************************************************
 * Copyright 2012-2015 Esri
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 ******************************************************************************/

import QtPositioning 5.3
import QtQuick 2.3
import QtQuick.Controls 1.2
import ArcGIS.Runtime 10.26
import ArcGIS.Runtime.Toolkit.Controls 1.0

Rectangle {
    width: 500
    height: 400

    Map {
        id: mainMap
        anchors.fill: parent
        wrapAroundEnabled: true
        focus: true

        ArcGISTiledMapServiceLayer {
            url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
        }

        PositionSource {
            id: position
        }

        NavigationToolbar {
            id: navigationToolbar
            map: mainMap
            anchors {
                top: parent.top
                left: parent.left
                margins: 10
            }
        }

        onStatusChanged: {
            if (status === Enums.MapStatusReady) {
                mainMap.positionDisplay.positionSource = position;
            }
        }
    }
}


/// base sprite object
Image {
	property int offsetX;	///< sprite horizontal offset
	property int offsetY;	///< sprite vertical offset
	fillMode: Image.Tile;	///< sprite image filling mode

	onOffsetYChanged,
	onOffsetXChanged: {
		this.style('background-position', '-' + this.offsetX + 'px -' + this.offsetY + 'px');
	}
}

Align sprite image to the left anchor by default

/// base sprite object
Image {
	property int offsetX;	///< sprite horizontal offset
	property int offsetY;	///< sprite vertical offset
	fillMode: Image.Tile;	///< sprite image filling mode
	horizontalAlignment: Image.AlignLeft;

	onOffsetYChanged,
	onOffsetXChanged: {
		this.style('background-position', '-' + this.offsetX + 'px -' + this.offsetY + 'px');
	}
}


import QtQuick 2.5
import QtQuick.Dialogs 1.2

Item {

    property var device

    MessageDialog {
        id: entry

        icon: StandardIcon.Critical
        title: qsTr("Reset PIV functionality")
        text: qsTr("Do you want to reset the PIV functionality for this YubiKey? This action will wipe all keys and certficates, and set PIN, PUK and Management Key to their default values.")
        standardButtons: StandardButton.Yes | StandardButton.No
        onYes: {
            device.piv_reset(function (error) {
                if (error) {
                    console.log(error)
                } else {
                    confirmation.open()
                }
            })
        }
        onNo: close()

    }

    MessageDialog {
        id: confirmation
        icon: StandardIcon.Information
        title: qsTr("PIV functionality has been reset.")
        text: qsTr("All data has been cleared and default PIN, PUK and Management Key are set.")
        standardButtons: StandardButton.Ok
    }

    function open() {
        return entry.open()
    }

}

Add "Please wait..." dialog to PIV reset

import QtQuick 2.5
import QtQuick.Dialogs 1.2

Item {

    property var device

    MessageDialog {
        id: entry

        icon: StandardIcon.Critical
        title: qsTr("Reset PIV functionality")
        text: qsTr("Do you want to reset the PIV functionality for this YubiKey? This action will wipe all keys and certficates, and set PIN, PUK and Management Key to their default values.")
        standardButtons: StandardButton.Yes | StandardButton.No
        onYes: {
            wait.open()
            device.piv_reset(function (error) {
                wait.close()
                if (error) {
                    console.log(error)
                } else {
                    confirmation.open()
                }
            })
        }
        onNo: close()

    }

    MessageDialog {
        id: wait
        icon: StandardIcon.Information
        title: entry.title
        text: qsTr("Please wait. Do not disconnect the YubiKey.")
        standardButtons: StandardButton.NoButton
    }

    MessageDialog {
        id: confirmation
        icon: StandardIcon.Information
        title: qsTr("PIV functionality has been reset.")
        text: qsTr("All data has been cleared and default PIN, PUK and Management Key are set.")
        standardButtons: StandardButton.Ok
    }

    function open() {
        return entry.open()
    }

}


Add instantiator, merge in add-frequency (still very broken)

import QtQuick 2.3

QtObject {
    Component.onCompleted: {
        var vn = registry.deserialize(context, JSON.stringify({
            type: "ConsoleOutputNode"
        }));
        if (vn) {
            graph.insertVideoNode(vn);
        } else {
            console.log("Could not instantiate ConsoleOutputNode");
        }
    }
}


import qbs.Utilities

Project {
    condition: {
        var result = qbs.targetOS.contains("macos");
        if (!result)
            console.info("Skip this test");
        return result;
    }
    property bool includeIconset

    CppApplication {
        Depends { name: "ib" }
        files: {
            var filez = ["main.c", "MainMenu.xib"];
            if (project.includeIconset)
                filez.push("empty.xcassets/empty.iconset");
            else if (Utilities.versionCompare(xcode.version, "5") >= 0)
                filez.push("empty.xcassets");
            if (qbs.hostOSVersionMinor >= 10 // need macOS 10.10 to build SBs
                    && cpp.minimumMacosVersion !== undefined
                    && Utilities.versionCompare(cpp.minimumMacosVersion, "10.10") >= 0)
                filez.push("Storyboard.storyboard");
            return filez;
        }
    }
}

Fix assetCatalog test for macOS 11.*

import qbs.Utilities

Project {
    condition: {
        var result = qbs.targetOS.contains("macos");
        if (!result)
            console.info("Skip this test");
        return result;
    }
    property bool includeIconset

    CppApplication {
        Depends { name: "ib" }
        files: {
            var filez = ["main.c", "MainMenu.xib"];
            if (project.includeIconset)
                filez.push("empty.xcassets/empty.iconset");
            else if (Utilities.versionCompare(xcode.version, "5") >= 0)
                filez.push("empty.xcassets");
            if ((qbs.hostOSVersionMajor >= 11
                 || qbs.hostOSVersionMinor >= 10) // need macOS 10.10 or higher to build SBs
                    && cpp.minimumMacosVersion !== undefined
                    && Utilities.versionCompare(cpp.minimumMacosVersion, "10.10") >= 0)
                filez.push("Storyboard.storyboard");
            return filez;
        }
    }
}


/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Dmitry Rozhkov <dmitry.rozhkov@jollamobile.com>
**
****************************************************************************/

import QtQuick 1.1
import Sailfish.Silica 1.0

import "../history.js" as History

ContextMenu {
    id: menu

    property string linkHref
    property string imageSrc

    MenuItem {
        visible: linkHref.length > 0
        //% "Open link in a new tab"
        text: qsTrId("sailfish_browser-me-open_link_in_new_tab")

        onClicked: {
            console.log("clicked 'open image in tab' (not fully implemeted yet)")
            History.addTab(linkHref, "")
        }
    }

    MenuItem {
        visible: imageSrc.length > 0
        //% "Open image in a new tab"
        text: qsTrId("sailfish_browser-me-open_image_in_new_tab")

        onClicked: {
            console.log("clicked 'open image in tab' (not fully implemeted yet)")
            History.addTab(imageSrc, "")
        }
    }

    MenuItem {
        visible: imageSrc.length > 0
        //% "Save by image URL as..."
        text: qsTrId("sailfish_browser-me-save_image_as")

        onClicked: console.log("clicked 'save image as' (not implemented yet)")
    }
}

Add title to context menu

/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Dmitry Rozhkov <dmitry.rozhkov@jollamobile.com>
**
****************************************************************************/

import QtQuick 1.1
import Sailfish.Silica 1.0

import "../history.js" as History

ContextMenu {
    id: menu

    property string linkHref
    property string imageSrc

    MenuItem {
        enabled: false
        truncationMode: TruncationMode.Fade
        text: linkHref ? linkHref : imageSrc
        font.pixelSize: theme.fontSizeSmall
        color: theme.primaryColor
    }

    MenuItem {
        visible: linkHref.length > 0
        //% "Open link in a new tab"
        text: qsTrId("sailfish_browser-me-open_link_in_new_tab")

        onClicked: {
            console.log("clicked 'open image in tab' (not fully implemeted yet)")
            History.addTab(linkHref, "")
        }
    }

    MenuItem {
        visible: imageSrc.length > 0
        //% "Open image in a new tab"
        text: qsTrId("sailfish_browser-me-open_image_in_new_tab")

        onClicked: {
            console.log("clicked 'open image in tab' (not fully implemeted yet)")
            History.addTab(imageSrc, "")
        }
    }

    MenuItem {
        visible: imageSrc.length > 0
        //% "Save by image URL as..."
        text: qsTrId("sailfish_browser-me-save_image_as")

        onClicked: console.log("clicked 'save image as' (not implemented yet)")
    }
}


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

import UM 1.0 as UM

Rectangle {
    id: base;

    width: UM.Theme.sizes.tooltip.width;
    height: label.height + UM.Theme.sizes.tooltip_margins.height * 2;
    color: UM.Theme.colors.tooltip;

    opacity: 0;
    Behavior on opacity { NumberAnimation { duration: 100; } }

    property alias text: label.text;

    function show(position) {
        x = position.x;
        y = position.y;
        base.opacity = 1;
    }

    function hide() {
        base.opacity = 0;
    }

    Label {
        id: label;
        anchors {
            top: parent.top;
            topMargin: UM.Theme.sizes.tooltip_margins.height;
            left: parent.left;
            leftMargin: UM.Theme.sizes.tooltip_margins.width;
            right: parent.right;
            rightMargin: UM.Theme.sizes.tooltip_margins.width;
        }

//         horizontalAlignment: Qt.AlignJustify;
        wrapMode: Text.Wrap;
    }
}

Make sure the description tooltip is not cutoff at the bottom of the window

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

import UM 1.0 as UM

Rectangle {
    id: base;

    width: UM.Theme.sizes.tooltip.width;
    height: label.height + UM.Theme.sizes.tooltip_margins.height * 2;
    color: UM.Theme.colors.tooltip;

    opacity: 0;
    Behavior on opacity { NumberAnimation { duration: 100; } }

    property alias text: label.text;

    function show(position) {
        if(position.y + base.height > parent.height) {
            x = position.x;
            y = parent.height - base.height;
        } else {
            x = position.x;
            y = position.y;
        }
        base.opacity = 1;
    }

    function hide() {
        base.opacity = 0;
    }

    Label {
        id: label;
        anchors {
            top: parent.top;
            topMargin: UM.Theme.sizes.tooltip_margins.height;
            left: parent.left;
            leftMargin: UM.Theme.sizes.tooltip_margins.width;
            right: parent.right;
            rightMargin: UM.Theme.sizes.tooltip_margins.width;
        }
        wrapMode: Text.Wrap;
        font: UM.Theme.fonts.default;
    }
}


/*
 * 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://themedimage/widgets/apps/contacts/contact-available";
                break;
            case TelepathyTypes.ConnectionPresenceTypeBusy:
                icon = "image://themedimage/widgets/apps/contacts/contact-busy";
                break;
            case TelepathyTypes.ConnectionPresenceTypeAway:
            case TelepathyTypes.ConnectionPresenceTypeExtendedAway:
                icon = "image://themedimage/widgets/apps/contacts/contact-idle";
                break;
            case TelepathyTypes.ConnectionPresenceTypeHidden:
            case TelepathyTypes.ConnectionPresenceTypeUnknown:
            case TelepathyTypes.ConnectionPresenceTypeError:
            default:
                icon = "";
                break;
            }
            return icon;
        }
    }
}

Rename the status icons according to the theme

/*
 * 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://themedimage/icons/status/status-available";
                break;
            case TelepathyTypes.ConnectionPresenceTypeBusy:
                icon = "image://themedimage/icons/status/status-busy";
                break;
            case TelepathyTypes.ConnectionPresenceTypeAway:
            case TelepathyTypes.ConnectionPresenceTypeExtendedAway:
                icon = "image://themedimage/icons/status/status-idle";
                break;
            case TelepathyTypes.ConnectionPresenceTypeHidden:
            case TelepathyTypes.ConnectionPresenceTypeUnknown:
            case TelepathyTypes.ConnectionPresenceTypeError:
            default:
                icon = "";
                break;
            }
            return icon;
        }
    }
}


import QtQuick 1.0
import "../components"

Rectangle {
    width: 540
    height: 340
    color: "green"
    id : rect

    Text {
        id : selctedLabel
        anchors.centerIn: parent
        text : editMenu.selected
    }

    ContextMenu {
        id : editMenu

        // MenuItem API:
        MenuItem { text : "blue"
                   onSelected : { rect.color = "blue" }
        }

        MenuItem { text : "red"
                   onSelected : { rect.color = "red" }
        }

        MenuItem { text : "pink"
                   onSelected : { rect.color = "pink" }
        }

        // ListModel API:
        // # no way to do onSelected.
        model: ListModel {
            id: menu
            ListElement { text: "Elememt1" }
            ListElement { text: "Elememt2" }
            ListElement { text: "Elememt2" }
        }
    }

    MouseArea {
        anchors.fill: parent
        acceptedButtons : Qt.RightButton
        onClicked: editMenu.show(mouseX, mouseY)
    }
}

Make menu example work a bit

import QtQuick 2.0
//import "../components"
import QtDesktop 0.2

Rectangle {
    width: 540
    height: 340
    color: "green"
    id : rect

    Text {
        id : selctedLabel
        anchors.centerIn: parent
        text : editMenu.selected
    }

    ContextMenu {
        id : editMenu

        // MenuItem API:
        MenuItem { text : "blue"
                   onTriggered: rect.color = "blue"
        }

        MenuItem { text : "red"
                   onTriggered: rect.color = "red"
        }

        MenuItem { text : "pink"
                   onTriggered: rect.color = "pink"
        }

        // ListModel API:
        // # no way to do onSelected.
//        model: ListModel {
//            id: menu
//            ListElement { text: "Elememt1" }
//            ListElement { text: "Elememt2" }
//            ListElement { text: "Elememt2" }
//        }
    }

    MouseArea {
        anchors.fill: parent
        acceptedButtons : Qt.RightButton
        onClicked: editMenu.showPopup(mouseX, mouseY, 0)
    }
}


import qbs 1.0

Project {
  name: "cjet"
  minimumQbsVersion: "1.4.0"

  qbsSearchPaths: "../qbs/"

  CppApplication {
    name: "cjet"

    Depends { name: "generateConfig" }
    Depends { name: "generateVersion" }

    cpp.warningLevel: "all"
    cpp.treatWarningsAsErrors: true
    cpp.positionIndependentCode: false
    cpp.includePaths: ["linux/epoll/", ".", buildDirectory]

    Group {
      name: "platform independent"
      files: [
        "*.c",
      ]
      cpp.cLanguageVersion: "c99"
    }

    Group {
      name: "cJSON"
      files: [
        "json/*.c",
      ]
      cpp.cLanguageVersion: "c99"
    }

    Group {
      name: "version file"
      files: [
        "version.h.in"
      ]
      fileTags: ["version_tag"]
    }

    Group {
      condition: qbs.targetOS.contains("linux")
      name: "config file"
      files: [
        "linux/epoll/config/config.h.in"
      ]
      fileTags: ["config_tag"]
    }

    Group {
      condition: qbs.targetOS.contains("linux")
      name: "linux specific"
      prefix: "linux/"
      files: [
        "*.c",
        "epoll/*.c",
      ]
      cpp.defines: "_GNU_SOURCE"
    }

    Properties {
      condition: qbs.toolchain.contains("gcc")
     // cpp.defines: outer.concat("gcc")
    }
  }
}

Use gnu99 standard for compiling linux specific files.

import qbs 1.0

Project {
  name: "cjet"
  minimumQbsVersion: "1.4.0"

  qbsSearchPaths: "../qbs/"

  CppApplication {
    name: "cjet"

    Depends { name: "generateConfig" }
    Depends { name: "generateVersion" }

    cpp.warningLevel: "all"
    cpp.treatWarningsAsErrors: true
    cpp.positionIndependentCode: false
    cpp.includePaths: ["linux/epoll/", ".", buildDirectory]

    Group {
      name: "platform independent"
      files: [
        "*.c",
      ]
      cpp.cLanguageVersion: "c99"
    }

    Group {
      name: "cJSON"
      files: [
        "json/*.c",
      ]
      cpp.cLanguageVersion: "c99"
    }

    Group {
      name: "version file"
      files: [
        "version.h.in"
      ]
      fileTags: ["version_tag"]
    }

    Group {
      condition: qbs.targetOS.contains("linux")
      name: "config file"
      files: [
        "linux/epoll/config/config.h.in"
      ]
      fileTags: ["config_tag"]
    }

    Group {
      condition: qbs.targetOS.contains("linux")
      name: "linux specific"
      prefix: "linux/"
      files: [
        "*.c",
        "epoll/*.c",
      ]
      cpp.defines: "_GNU_SOURCE"
      cpp.cFlags: "-std=gnu99"
    }

    Properties {
      condition: qbs.toolchain.contains("gcc")
     // cpp.defines: outer.concat("gcc")
    }
  }
}


/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jollamobile.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.0
import Sailfish.Silica 1.0
import "pages"

ApplicationWindow {
    id: window

    _defaultPageOrientations: WebUtils.firstUseDone ? Orientation.Landscape | Orientation.Portrait | Orientation.LandscapeInverted : Orientation.Portrait
    initialPage: Component {BrowserPage {}}
    cover: undefined
}

Use only normal landscape orientation

/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jollamobile.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.0
import Sailfish.Silica 1.0
import "pages"

ApplicationWindow {
    id: window

    _defaultPageOrientations: WebUtils.firstUseDone ? Orientation.Landscape | Orientation.Portrait  : Orientation.Portrait
    initialPage: Component {BrowserPage {}}
    cover: undefined
}


import QtQuick 2.0
import Sailfish.Silica 1.0
import harbour.zatraty 1.0

Page {
    id: hystoryPage

    SilicaListView {
        id: listView
        model: DateListModel {
            id: monthsModel
            group: DateListModel.ByMonth
            reverse: true
        }
        anchors.fill: parent

        header: PageHeader {
            title: qsTr("History")
        }

        delegate: BackgroundItem {
            id: delegate
            height: 160

            ProgressBar {
                id: percentIndicator
                width: parent.width
                anchors.verticalCenter: parent.verticalCenter
                minimumValue: 0
                maximumValue: ExpenseModel.totalAmount()
                value: ExpenseModel.totalMonthAmount(date)
                valueText: qsTr("%1 %2", "1 is amount and 2 is currency")
                                                          .arg(value)
                                                          .arg(Settings.currency)
                label: Qt.formatDate(date, "MMMM yyyy")
            }

            onClicked: {
                pageStack.push(Qt.resolvedUrl("MonthSummaryPage.qml"), { "period": date })
            }
        }
        VerticalScrollDecorator {}
    }
}

Align value labels on hystory page

import QtQuick 2.0
import Sailfish.Silica 1.0
import harbour.zatraty 1.0

Page {
    id: hystoryPage

    SilicaListView {
        id: listView
        model: DateListModel {
            id: monthsModel
            group: DateListModel.ByMonth
            reverse: true
        }
        anchors.fill: parent

        header: PageHeader {
            title: qsTr("History")
        }

        delegate: ListItem {
            id: delegate
            height: 150

            Label {
                id: valueLabel
                x: 50
                text: qsTr("%1 %2", "1 is amount and 2 is currency")
                                                        .arg(percentIndicator.value)
                                                        .arg(Settings.currency)
            }

            ProgressBar {
                id: percentIndicator
                width: parent.width
                minimumValue: 0
                maximumValue: ExpenseModel.totalAmount()
                value: ExpenseModel.totalMonthAmount(date)
                label: Qt.formatDate(date, "MMMM yyyy")
            }

            onClicked: {
                pageStack.push(Qt.resolvedUrl("MonthSummaryPage.qml"), { "period": date })
            }
        }
        VerticalScrollDecorator {}
    }
}


import qbs 1.0

QtcLibrary {
    name: "ClangBackEndIpc"

    Depends { name: "Qt.network" }
    Depends { name: "Sqlite" }

    cpp.defines: base.concat("CLANGIPC_LIBRARY")
    cpp.includePaths: base.concat(".")

    Group {
        files: [
            "*.h",
            "*.cpp"
        ]
    }

    Export {
        Depends { name: "Sqlite" }
        Depends { name: "Qt.network" }
        cpp.includePaths: [
            "."
        ]
    }
}

Fix qbs build on Windows.

import qbs 1.0

QtcLibrary {
    name: "ClangBackEndIpc"

    Depends { name: "Qt.network" }
    Depends { name: "Sqlite" }

    cpp.defines: base.concat("CLANGBACKENDIPC_LIBRARY")
    cpp.includePaths: base.concat(".")

    Group {
        files: [
            "*.h",
            "*.cpp"
        ]
    }

    Export {
        Depends { name: "Sqlite" }
        Depends { name: "Qt.network" }
        cpp.includePaths: [
            "."
        ]
    }
}


import QtQuick 2.2
import QtQuick.Controls 1.2

import UM 1.0 as UM

Item {
    Button {
        id: resetRotationButton

        anchors.bottom: parent.bottom;

        text: qsTr('Reset Rotation')
        iconSource: UM.Theme.icons.rotate_reset;
        tooltip: qsTr("Reset the rotation of the current selection.");

        style: UM.Theme.styles.tool_button;

        onClicked: UM.ActiveTool.triggerAction('resetRotation');
    }
}

Add a chechbox to the rotation tool panel to disable rotation snapping

import QtQuick 2.2
import QtQuick.Controls 1.2

import UM 1.0 as UM

Item {
    Button {
        id: resetRotationButton

        anchors.bottom: parent.bottom;

        text: qsTr('Reset')
        iconSource: UM.Theme.icons.rotate_reset;
        tooltip: qsTr("Reset the rotation of the current selection.");

        style: UM.Theme.styles.tool_button;

        onClicked: UM.ActiveTool.triggerAction('resetRotation');
    }

    CheckBox {
        anchors.left: resetRotationButton.right;
        anchors.leftMargin: UM.Theme.sizes.default_margin.width;
        anchors.top: resetRotationButton.top;

        text: qsTr("Snap Rotation");

        checked: UM.ActiveTool.getProperty('RotationSnap');
        onClicked: UM.ActiveTool.setProperty('RotationSnap', checked);
    }
}


/*
 * Copyright (C) 2015 Dan Leinir Turthra Jensen <admin@leinir.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) version 3, or any
 * later version accepted by the membership of KDE e.V. (or its
 * successor approved by the membership of KDE e.V.), which shall
 * act as a proxy defined in Section 6 of version 3 of the license.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

import QtQuick 2.1
import org.kde.plasma.extras 2.0 as PlasmaExtras

Row {
    id: root;
    property string text;
    width: parent.width;
    height: childrenRect.height;
    Item {
        width: units.largeSpacing;
        height: 1;
    }
    PlasmaExtras.Heading {
        width: parent.width - units.largeSpacing;
        text: root.text;
        height: paintedHeight;
    }
}

Switch this to using the Kirigami page header/breadcrumbs component instead

/*
 * Copyright (C) 2015 Dan Leinir Turthra Jensen <admin@leinir.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) version 3, or any
 * later version accepted by the membership of KDE e.V. (or its
 * successor approved by the membership of KDE e.V.), which shall
 * act as a proxy defined in Section 6 of version 3 of the license.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

import QtQuick 2.1
import org.kde.plasma.extras 2.0 as PlasmaExtras

/// FIXME Switch this to using the Kirigami page header/breadcrumbs component instead
Row {
    id: root;
    property string text;
    width: parent.width;
    height: childrenRect.height;
    Item {
        width: units.largeSpacing;
        height: 1;
    }
    PlasmaExtras.Heading {
        width: parent.width - units.largeSpacing;
        text: root.text;
        height: paintedHeight;
    }
}


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

import UM 1.0 as UM

UM.Dialog {
    id: base

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

    Label {
        text: "Cura";
    }

    rightButtons: Button {
        text: "Close";

        onClicked: base.visible = false;
    }
}


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

import QtQuick 2.1
import QtQuick.Controls 1.1

Item
{
    id: base

    property alias text: textArea.text
    property alias wrapMode: textArea.wrapMode

    signal editingFinished();

    property bool readOnly: false

    width: textArea.width
    height: textArea.height

    TextArea
    {
        id: textArea

        enabled: !base.readOnly
        opacity: base.readOnly ? 0.5 : 1.0

        anchors.fill: parent

        Keys.onReturnPressed:
        {
            base.editingFinished()
        }

        Keys.onEnterPressed:
        {
            base.editingFinished()
        }

        onActiveFocusChanged:
        {
            if(!activeFocus)
            {
                base.editingFinished()
            }
        }
    }

    Label
    {
        visible: base.readOnly
        text: textArea.text

        anchors.fill: parent
        anchors.margins: textArea.__style ? textArea.__style.textMargin : 4

        color: palette.buttonText
    }

    SystemPalette { id: palette }
}

Fix rendering of readonly description/adhesion info

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

import QtQuick 2.1
import QtQuick.Controls 1.1

Item
{
    id: base

    property alias text: textArea.text
    property alias wrapMode: textArea.wrapMode

    signal editingFinished();

    property bool readOnly: false

    width: textArea.width
    height: textArea.height

    TextArea
    {
        id: textArea

        enabled: !base.readOnly
        opacity: base.readOnly ? 0.5 : 1.0

        anchors.fill: parent

        Keys.onReturnPressed:
        {
            base.editingFinished()
        }

        Keys.onEnterPressed:
        {
            base.editingFinished()
        }

        onActiveFocusChanged:
        {
            if(!activeFocus)
            {
                base.editingFinished()
            }
        }
    }
}


import qbs

Module {
	property string moduleInstallDir: "bin"
	property string toolInstallDir: "bin"
	property string qmlExtensionInstallDir: "QML"
	property string qmlPluginInstallDir: "plugins"

	property string externalLibDir: project.sourceDirectory + "/external/deploy"
}

Add properties for external directories and use `setupRunEnvironment` script.

import qbs

Module {
	property string moduleInstallDir: "bin"
	property string toolInstallDir: "bin"
	property string qmlExtensionInstallDir: "QML"
	property string qmlPluginInstallDir: "plugins"

	property string externalDeployDir: project.sourceDirectory + "/external/deploy"
	property string externalLibDir: externalDeployDir + "/lib"
	property string externalIncludeDir: externalDeployDir + "/include"

	setupRunEnvironment: {
		Environment.putEnv("PATH", externalLibDir + qbs.pathListSeparator + Environment.getEnv("PATH"))
	}
}


import qbs 1.0

Project {
    name: "dewalls"

    StaticLibrary {
        name: "dewalls"
        Depends { name: "cpp" }
        Depends { name: "Qt"; submodules: ["core"] }

        cpp.includePaths: ["src"]

        Export {
            Depends { name: "cpp" }
            cpp.includePaths: ["src"]
        }

        files: [
            "src/*.cpp",
            "src/*.h",
            "test/approx.h",
            "test/generaltests.cpp",
        ]
    }

    CppApplication {
        name: "dewalls-test"
        consoleApplication: true
        type: "application"

        Depends { name: "cpp" }
        Depends { name: "Qt"; submodules: ["core"] }

        cpp.includePaths: ["src"]

        files: [
            "src/*.cpp",
            "src/*.h",
            "test/*.cpp",
            "test/*.h",
        ]
    }
}

Fix C++ compiling errors on linux

import qbs 1.0

Project {
    name: "dewalls"

    StaticLibrary {
        name: "dewalls"
        Depends { name: "cpp" }
        Depends { name: "Qt"; submodules: ["core"] }

        cpp.includePaths: ["src"]

        Export {
            Depends { name: "cpp" }
            cpp.includePaths: ["src"]
        }

        Properties {
            condition: qbs.targetOS.contains("osx") || qbs.targetOS.contains("linux")
            cpp.cxxFlags: [
                "-stdlib=libstdc++", //Needed for protoc
                "-std=c++11", //For c++11 support
                "-Werror" //Treat warnings as errors
            ]
        }

        Properties {
            condition: qbs.targetOS.contains("osx")

            cpp.dynamicLibraries: [
                "c++"
            ]
        }

        files: [
            "src/*.cpp",
            "src/*.h",
            "test/approx.h",
            "test/generaltests.cpp",
        ]
    }

    CppApplication {
        name: "dewalls-test"
        consoleApplication: true
        type: "application"

        Depends { name: "cpp" }
        Depends { name: "Qt"; submodules: ["core"] }

        cpp.includePaths: ["src"]

        Properties {
            condition: qbs.targetOS.contains("osx") || qbs.targetOS.contains("linux")
            cpp.cxxFlags: [
                "-stdlib=libstdc++", //Needed for protoc
                "-std=c++11", //For c++11 support
                "-Werror" //Treat warnings as errors
            ]
        }

        Properties {
            condition: qbs.targetOS.contains("osx")

            cpp.dynamicLibraries: [
                "c++"
            ]
        }

        files: [
            "src/*.cpp",
            "src/*.h",
            "test/*.cpp",
            "test/*.h",
        ]
    }
}


import QtQuick 2.0

Rectangle {
    anchors {
        bottom: parent.bottom
        left: background.left
        margins: splitState=='viewer' ? 5 : 0
    }
    radius: 3 * scaleRatio
    height: (os_type[platform]=='android' ? 53 : 44 ) * scaleRatio
    width: splitState=='viewer' ? 50 * scaleRatio : background.width
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#70787F" }
        GradientStop { position: 1.0; color: "#383C40" }
    }
    CustomButton {
        id: viewSwitchButton
        anchors { top: parent.top; left: parent.left }
        icon.text: "\uf0db"
        defaultColor: splitState =='splitted' ? "#FED146" : "#CAD8E5"
        onClicked: {
            if (splitState == 'splitted')
                splitState = 'viewer';
            else if (splitState == 'viewer')
                splitState = 'editor';
            else
                splitState = 'splitted';
            view.state = splitState;
        }
    }
    CustomButton {
        id: exportButton
        visible: splitState != 'viewer'
        anchors { top: parent.top; right: parent.right; }
        icon.text: "\uf1d8"
        onClicked: {
            Qt.openUrlExternally("mailto:?subject=Terrarium project&body="+editor.text);
        }
    }
}

Change icon based on view state

import QtQuick 2.0

Rectangle {
    anchors {
        bottom: parent.bottom
        left: background.left
        margins: splitState=='viewer' ? 5 : 0
    }
    radius: 3 * scaleRatio
    height: (os_type[platform]=='android' ? 53 : 44 ) * scaleRatio
    width: splitState=='viewer' ? 50 * scaleRatio : background.width
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#70787F" }
        GradientStop { position: 1.0; color: "#383C40" }
    }
    CustomButton {
        id: viewSwitchButton
        anchors { top: parent.top; left: parent.left }
        icon.text: splitState=='viewer' ? "\uf121" : "\uf0db"
        defaultColor: splitState =='splitted' ? "#FED146" : "#CAD8E5"
        onClicked: {
            if (splitState == 'splitted')
                splitState = 'viewer';
            else if (splitState == 'viewer')
                splitState = 'editor';
            else
                splitState = 'splitted';
            view.state = splitState;
        }
    }
    CustomButton {
        id: exportButton
        visible: splitState != 'viewer'
        anchors { top: parent.top; right: parent.right; }
        icon.text: "\uf1d8"
        onClicked: {
            Qt.openUrlExternally("mailto:?subject=Terrarium project&body="+editor.text);
        }
    }
}


import QtQuick.Layouts 1.4
import QtQuick 2.4
import QtQuick.Controls 2.0
import org.kde.kirigami 2.4 as Kirigami

import Mycroft 1.0 as Mycroft

Mycroft.ProportionalDelegate {
    id: systemTextFrame
    skillBackgroundColorOverlay: "#000000"
    property bool hasTitle: sessionData.title.length > 0 ? true : false

    Component.onCompleted: {
        console.log(hasTitle)
    }

    Mycroft.AutoFitLabel {
        id: systemTextFrameTitle
        Layout.fillWidth: true
        Layout.preferredHeight: proportionalGridUnit * 20
        wrapMode: Text.Wrap
        visible: hasTitle
        enabled: hasTitle
        font.family: "Noto Sans"
        font.weight: Font.Bold
        text: sessionData.title
    }

    Mycroft.AutoFitLabel {
        id: systemTextFrameMainBody
        Layout.fillWidth: true
        Layout.preferredHeight: proportionalGridUnit * 30
        wrapMode: Text.Wrap
        font.family: "Noto Sans"
        font.weight: Font.Bold
        text: sessionData.text
    }
}

Use the correct delegate and fix layouts

import QtQuick.Layouts 1.4
import QtQuick 2.4
import QtQuick.Controls 2.0
import org.kde.kirigami 2.4 as Kirigami

import Mycroft 1.0 as Mycroft

Mycroft.Delegate {
    id: systemTextFrame
    skillBackgroundColorOverlay: "#000000"
    property bool hasTitle: sessionData.title.length > 0 ? true : false

    Component.onCompleted: {
        console.log(hasTitle)
    }

    contentItem: ColumnLayout {
        Label {
            id: systemTextFrameTitle
            Layout.fillWidth: true
            font.pixelSize: Math.min(systemTextFrame.height/4, Math.max(systemTextFrame.height/10, systemTextFrameMainBody.fontInfo.pixelSize * 1.4))
            wrapMode: Text.Wrap
            horizontalAlignment: Text.AlignHCenter
            visible: hasTitle
            enabled: hasTitle
            font.family: "Noto Sans"
            font.weight: Font.Bold
            text: sessionData.title
        }

        Mycroft.AutoFitLabel {
            id: systemTextFrameMainBody
            Layout.fillWidth: true
            Layout.fillHeight: true
            wrapMode: Text.Wrap
            font.family: "Noto Sans"
            font.weight: Font.Bold
            text: sessionData.text
        }
    }
}