From 88f140ddd7f634ad4411f4d16cae51a93eb856b7 Mon Sep 17 00:00:00 2001
From: Jens Bache-Wiig <jens.bache-wiig@nokia.com>
Date: Mon, 21 Feb 2011 10:52:17 +0100
Subject: [PATCH] Added widgets

---
 components/Button.qml                         |  27 +
 components/ButtonRow.qml                      |   5 +
 components/CheckBox.qml                       |  26 +
 components/ChoiceList.qml                     |  52 ++
 components/GroupBox.qml                       |  27 +
 components/ProgressBar.qml                    |  31 +
 components/RadioButton.qml                    |  26 +
 components/ScrollArea.qml                     | 103 ++++
 components/ScrollBar.qml                      | 109 ++++
 components/Slider.qml                         |  31 +
 components/SpinBox.qml                        |  91 +++
 components/Switch.qml                         |  22 +
 components/Tab.qml                            |   7 +
 components/TabBar.qml                         |  90 +++
 components/TabFrame.qml                       |  72 +++
 components/TextArea.qml                       |  44 ++
 components/TextField.qml                      |  52 ++
 components/TextScrollArea.qml                 |  31 +
 components/ToolBar.qml                        |  12 +
 components/ToolButton.qml                     |  18 +
 components/custom/BasicButton.qml             |  44 ++
 components/custom/BusyIndicator.qml           |  27 +
 components/custom/Button.qml                  |  39 ++
 components/custom/ButtonBlock.qml             | 216 +++++++
 components/custom/ButtonColumn.qml            |  44 ++
 components/custom/ButtonGroup.js              | 127 ++++
 components/custom/ButtonRow.qml               |  43 ++
 components/custom/CheckBox.qml                |  49 ++
 components/custom/ChoiceList.qml              |  85 +++
 components/custom/ProgressBar.qml             |  80 +++
 components/custom/RadioButton.qml             |  13 +
 components/custom/ScrollDecorator.qml         |  20 +
 components/custom/ScrollIndicator.qml         |  56 ++
 components/custom/Slider.qml                  | 291 ++++++++++
 components/custom/SpinBox.qml                 | 142 +++++
 components/custom/Switch.qml                  |  85 +++
 components/custom/TextArea.qml                | 156 +++++
 components/custom/TextField.qml               | 196 +++++++
 .../custom/behaviors/ButtonBehavior.qml       |  31 +
 .../custom/behaviors/ModalPopupBehavior.qml   |  90 +++
 .../behaviors/TextEditMouseBehavior.qml       | 266 +++++++++
 components/custom/components.pro              |  49 ++
 components/custom/private/ChoiceListPopup.qml | 269 +++++++++
 components/custom/qmldir                      |  17 +
 .../styles/default/BasicButtonStyle.qml       |   8 +
 .../styles/default/BusyIndicatorStyle.qml     |  21 +
 .../styles/default/ButtonBlockStyle.qml       |  77 +++
 .../custom/styles/default/ButtonStyle.qml     | 102 ++++
 .../custom/styles/default/CheckBoxStyle.qml   |  34 ++
 .../custom/styles/default/ChoiceListStyle.qml | 100 ++++
 .../styles/default/ProgressBarStyle.qml       | 142 +++++
 .../styles/default/RadioButtonStyle.qml       |  34 ++
 .../styles/default/ScrollIndicatorStyle.qml   |  18 +
 .../custom/styles/default/SliderStyle.qml     | 110 ++++
 .../custom/styles/default/SpinBoxStyle.qml    |  73 +++
 .../custom/styles/default/SwitchStyle.qml     |  71 +++
 .../custom/styles/default/TextFieldStyle.qml  |  41 ++
 .../styles/default/images/button_normal.png   | Bin 0 -> 877 bytes
 .../styles/default/images/button_pressed.png  | Bin 0 -> 803 bytes
 .../default/images/buttongroup_h_normal.png   | Bin 0 -> 482 bytes
 .../default/images/buttongroup_h_pressed.png  | Bin 0 -> 386 bytes
 .../styles/default/images/checkbox_check.png  | Bin 0 -> 557 bytes
 .../custom/styles/default/images/handle.png   | Bin 0 -> 1529 bytes
 .../styles/default/images/lineedit_normal.png | Bin 0 -> 794 bytes
 .../images/progress-bar-background.png        | Bin 0 -> 484 bytes
 .../default/images/progress-bar-bar.png       | Bin 0 -> 548 bytes
 .../default/images/progressbar_fill.png       | Bin 0 -> 992 bytes
 .../default/images/progressbar_groove.png     | Bin 0 -> 492 bytes
 .../images/progressbar_indeterminate.png      | Bin 0 -> 1152 bytes
 .../default/images/progressbar_overlay.png    | Bin 0 -> 284 bytes
 .../custom/styles/default/images/qt-logo.png  | Bin 0 -> 954 bytes
 .../default/images/radiobutton_check.png      | Bin 0 -> 1331 bytes
 .../images/radiobutton_check_white.png        | Bin 0 -> 1310 bytes
 .../default/images/radiobutton_normal.png     | Bin 0 -> 1752 bytes
 .../default/images/slider-background.png      | Bin 0 -> 293 bytes
 .../default/images/slider-handle-active.png   | Bin 0 -> 506 bytes
 .../styles/default/images/slider-handle.png   | Bin 0 -> 516 bytes
 .../custom/styles/default/images/slider.png   | Bin 0 -> 617 bytes
 .../styles/default/images/spinbox_down.png    | Bin 0 -> 347 bytes
 .../styles/default/images/spinbox_up.png      | Bin 0 -> 341 bytes
 .../custom/styles/default/images/spinner.png  | Bin 0 -> 2629 bytes
 .../styles/default/images/switch_normal.png   | Bin 0 -> 834 bytes
 .../styles/default/images/switch_pressed.png  | Bin 0 -> 709 bytes
 .../styles/default/tools/ColorConverter.qml   |  59 ++
 components/custom/visuals/AdjoiningCorner.qml |  31 +
 components/custom/visuals/AdjoiningVisual.qml |  50 ++
 components/images/folder_new.png              | Bin 0 -> 1199 bytes
 components/plugin/qmldir                      |   1 +
 components/src.pro                            |   2 +
 components/styleitem/qstyleitem.cpp           | 547 ++++++++++++++++++
 components/styleitem/qstyleitem.h             | 197 +++++++
 components/styleitem/qstyleplugin.cpp         |  83 +++
 components/styleitem/qstyleplugin.h           |  55 ++
 components/styleitem/styleitem.pro            |  38 ++
 src/Button.qml                                |  27 +
 src/ButtonRow.qml                             |   5 +
 src/CheckBox.qml                              |  26 +
 src/ChoiceList.qml                            |  52 ++
 src/GroupBox.qml                              |  27 +
 src/ProgressBar.qml                           |  31 +
 src/RadioButton.qml                           |  26 +
 src/ScrollArea.qml                            | 103 ++++
 src/ScrollBar.qml                             | 109 ++++
 src/Slider.qml                                |  31 +
 src/SpinBox.qml                               |  91 +++
 src/Switch.qml                                |  22 +
 src/Tab.qml                                   |   7 +
 src/TabBar.qml                                |  90 +++
 src/TabFrame.qml                              |  72 +++
 src/TextArea.qml                              |  44 ++
 src/TextField.qml                             |  52 ++
 src/TextScrollArea.qml                        |  31 +
 src/ToolBar.qml                               |  12 +
 src/ToolButton.qml                            |  18 +
 src/components/ButtonGroup.js                 | 127 ++++
 src/components/components.pro                 |  49 ++
 src/components/qmldir                         |  17 +
 src/images/folder_new.png                     | Bin 0 -> 1199 bytes
 src/plugin/qmldir                             |   1 +
 src/styleitem/styleitem.pro                   |  38 ++
 src/widgets/Button.qml                        |  27 +
 src/widgets/ButtonRow.qml                     |   5 +
 src/widgets/CheckBox.qml                      |  26 +
 src/widgets/ChoiceList.qml                    |  52 ++
 src/widgets/GroupBox.qml                      |  27 +
 src/widgets/ProgressBar.qml                   |  31 +
 src/widgets/RadioButton.qml                   |  26 +
 src/widgets/ScrollArea.qml                    | 103 ++++
 src/widgets/ScrollBar.qml                     | 109 ++++
 src/widgets/Slider.qml                        |  31 +
 src/widgets/SpinBox.qml                       |  91 +++
 src/widgets/Switch.qml                        |  22 +
 src/widgets/Tab.qml                           |   7 +
 src/widgets/TabBar.qml                        |  90 +++
 src/widgets/TabFrame.qml                      |  72 +++
 src/widgets/TextArea.qml                      |  44 ++
 src/widgets/TextField.qml                     |  52 ++
 src/widgets/TextScrollArea.qml                |  31 +
 src/widgets/ToolBar.qml                       |  12 +
 src/widgets/ToolButton.qml                    |  18 +
 140 files changed, 7189 insertions(+)
 create mode 100644 components/Button.qml
 create mode 100644 components/ButtonRow.qml
 create mode 100644 components/CheckBox.qml
 create mode 100644 components/ChoiceList.qml
 create mode 100644 components/GroupBox.qml
 create mode 100644 components/ProgressBar.qml
 create mode 100644 components/RadioButton.qml
 create mode 100644 components/ScrollArea.qml
 create mode 100644 components/ScrollBar.qml
 create mode 100644 components/Slider.qml
 create mode 100644 components/SpinBox.qml
 create mode 100644 components/Switch.qml
 create mode 100644 components/Tab.qml
 create mode 100644 components/TabBar.qml
 create mode 100644 components/TabFrame.qml
 create mode 100644 components/TextArea.qml
 create mode 100644 components/TextField.qml
 create mode 100644 components/TextScrollArea.qml
 create mode 100644 components/ToolBar.qml
 create mode 100644 components/ToolButton.qml
 create mode 100644 components/custom/BasicButton.qml
 create mode 100644 components/custom/BusyIndicator.qml
 create mode 100644 components/custom/Button.qml
 create mode 100644 components/custom/ButtonBlock.qml
 create mode 100644 components/custom/ButtonColumn.qml
 create mode 100644 components/custom/ButtonGroup.js
 create mode 100644 components/custom/ButtonRow.qml
 create mode 100644 components/custom/CheckBox.qml
 create mode 100644 components/custom/ChoiceList.qml
 create mode 100644 components/custom/ProgressBar.qml
 create mode 100644 components/custom/RadioButton.qml
 create mode 100644 components/custom/ScrollDecorator.qml
 create mode 100644 components/custom/ScrollIndicator.qml
 create mode 100644 components/custom/Slider.qml
 create mode 100644 components/custom/SpinBox.qml
 create mode 100644 components/custom/Switch.qml
 create mode 100644 components/custom/TextArea.qml
 create mode 100644 components/custom/TextField.qml
 create mode 100644 components/custom/behaviors/ButtonBehavior.qml
 create mode 100644 components/custom/behaviors/ModalPopupBehavior.qml
 create mode 100644 components/custom/behaviors/TextEditMouseBehavior.qml
 create mode 100644 components/custom/components.pro
 create mode 100644 components/custom/private/ChoiceListPopup.qml
 create mode 100644 components/custom/qmldir
 create mode 100644 components/custom/styles/default/BasicButtonStyle.qml
 create mode 100644 components/custom/styles/default/BusyIndicatorStyle.qml
 create mode 100644 components/custom/styles/default/ButtonBlockStyle.qml
 create mode 100644 components/custom/styles/default/ButtonStyle.qml
 create mode 100644 components/custom/styles/default/CheckBoxStyle.qml
 create mode 100644 components/custom/styles/default/ChoiceListStyle.qml
 create mode 100644 components/custom/styles/default/ProgressBarStyle.qml
 create mode 100644 components/custom/styles/default/RadioButtonStyle.qml
 create mode 100644 components/custom/styles/default/ScrollIndicatorStyle.qml
 create mode 100644 components/custom/styles/default/SliderStyle.qml
 create mode 100644 components/custom/styles/default/SpinBoxStyle.qml
 create mode 100644 components/custom/styles/default/SwitchStyle.qml
 create mode 100644 components/custom/styles/default/TextFieldStyle.qml
 create mode 100644 components/custom/styles/default/images/button_normal.png
 create mode 100644 components/custom/styles/default/images/button_pressed.png
 create mode 100644 components/custom/styles/default/images/buttongroup_h_normal.png
 create mode 100644 components/custom/styles/default/images/buttongroup_h_pressed.png
 create mode 100644 components/custom/styles/default/images/checkbox_check.png
 create mode 100644 components/custom/styles/default/images/handle.png
 create mode 100644 components/custom/styles/default/images/lineedit_normal.png
 create mode 100644 components/custom/styles/default/images/progress-bar-background.png
 create mode 100644 components/custom/styles/default/images/progress-bar-bar.png
 create mode 100644 components/custom/styles/default/images/progressbar_fill.png
 create mode 100644 components/custom/styles/default/images/progressbar_groove.png
 create mode 100644 components/custom/styles/default/images/progressbar_indeterminate.png
 create mode 100644 components/custom/styles/default/images/progressbar_overlay.png
 create mode 100644 components/custom/styles/default/images/qt-logo.png
 create mode 100644 components/custom/styles/default/images/radiobutton_check.png
 create mode 100644 components/custom/styles/default/images/radiobutton_check_white.png
 create mode 100644 components/custom/styles/default/images/radiobutton_normal.png
 create mode 100644 components/custom/styles/default/images/slider-background.png
 create mode 100644 components/custom/styles/default/images/slider-handle-active.png
 create mode 100644 components/custom/styles/default/images/slider-handle.png
 create mode 100644 components/custom/styles/default/images/slider.png
 create mode 100644 components/custom/styles/default/images/spinbox_down.png
 create mode 100644 components/custom/styles/default/images/spinbox_up.png
 create mode 100644 components/custom/styles/default/images/spinner.png
 create mode 100644 components/custom/styles/default/images/switch_normal.png
 create mode 100644 components/custom/styles/default/images/switch_pressed.png
 create mode 100644 components/custom/styles/default/tools/ColorConverter.qml
 create mode 100644 components/custom/visuals/AdjoiningCorner.qml
 create mode 100644 components/custom/visuals/AdjoiningVisual.qml
 create mode 100644 components/images/folder_new.png
 create mode 100644 components/plugin/qmldir
 create mode 100644 components/src.pro
 create mode 100644 components/styleitem/qstyleitem.cpp
 create mode 100644 components/styleitem/qstyleitem.h
 create mode 100644 components/styleitem/qstyleplugin.cpp
 create mode 100644 components/styleitem/qstyleplugin.h
 create mode 100644 components/styleitem/styleitem.pro
 create mode 100644 src/Button.qml
 create mode 100644 src/ButtonRow.qml
 create mode 100644 src/CheckBox.qml
 create mode 100644 src/ChoiceList.qml
 create mode 100644 src/GroupBox.qml
 create mode 100644 src/ProgressBar.qml
 create mode 100644 src/RadioButton.qml
 create mode 100644 src/ScrollArea.qml
 create mode 100644 src/ScrollBar.qml
 create mode 100644 src/Slider.qml
 create mode 100644 src/SpinBox.qml
 create mode 100644 src/Switch.qml
 create mode 100644 src/Tab.qml
 create mode 100644 src/TabBar.qml
 create mode 100644 src/TabFrame.qml
 create mode 100644 src/TextArea.qml
 create mode 100644 src/TextField.qml
 create mode 100644 src/TextScrollArea.qml
 create mode 100644 src/ToolBar.qml
 create mode 100644 src/ToolButton.qml
 create mode 100644 src/components/ButtonGroup.js
 create mode 100644 src/components/components.pro
 create mode 100644 src/components/qmldir
 create mode 100644 src/images/folder_new.png
 create mode 100644 src/plugin/qmldir
 create mode 100644 src/styleitem/styleitem.pro
 create mode 100644 src/widgets/Button.qml
 create mode 100644 src/widgets/ButtonRow.qml
 create mode 100644 src/widgets/CheckBox.qml
 create mode 100644 src/widgets/ChoiceList.qml
 create mode 100644 src/widgets/GroupBox.qml
 create mode 100644 src/widgets/ProgressBar.qml
 create mode 100644 src/widgets/RadioButton.qml
 create mode 100644 src/widgets/ScrollArea.qml
 create mode 100644 src/widgets/ScrollBar.qml
 create mode 100644 src/widgets/Slider.qml
 create mode 100644 src/widgets/SpinBox.qml
 create mode 100644 src/widgets/Switch.qml
 create mode 100644 src/widgets/Tab.qml
 create mode 100644 src/widgets/TabBar.qml
 create mode 100644 src/widgets/TabFrame.qml
 create mode 100644 src/widgets/TextArea.qml
 create mode 100644 src/widgets/TextField.qml
 create mode 100644 src/widgets/TextScrollArea.qml
 create mode 100644 src/widgets/ToolBar.qml
 create mode 100644 src/widgets/ToolButton.qml

diff --git a/components/Button.qml b/components/Button.qml
new file mode 100644
index 000000000..496d37df2
--- /dev/null
+++ b/components/Button.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Button {
+    id:button
+
+    property int buttonHeight: Math.max(22, styleitem.sizeFromContents(100, 6).height)
+    height: buttonHeight
+
+    QStyleItem {
+        id:styleitem
+        elementType:"button"
+        sunken: pressed
+        raised: !pressed
+        hover: containsMouse
+        enabled:button.enabled
+        text:button.text
+    }
+
+    background:
+    QStyleBackground {
+        style:styleitem
+        anchors.fill:parent
+    }
+}
+
diff --git a/components/ButtonRow.qml b/components/ButtonRow.qml
new file mode 100644
index 000000000..623c5f442
--- /dev/null
+++ b/components/ButtonRow.qml
@@ -0,0 +1,5 @@
+import QtQuick 1.0
+import "../../../components" as Components
+
+Components.ButtonRow {
+}
diff --git a/components/CheckBox.qml b/components/CheckBox.qml
new file mode 100644
index 000000000..632dce2d4
--- /dev/null
+++ b/components/CheckBox.qml
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.CheckBox{
+    id:checkbox
+    property variant text
+    width:100
+    height:18
+
+    background: QStyleBackground {
+        id:styleitem
+        style:QStyleItem {
+            elementType:"checkbox"
+            sunken:pressed
+            on:checked || pressed
+            hover:containsMouse
+            text:checkbox.text
+            enabled:checkbox.enabled
+        }
+    }
+    checkmark: null
+}
+
diff --git a/components/ChoiceList.qml b/components/ChoiceList.qml
new file mode 100644
index 000000000..5015fbefb
--- /dev/null
+++ b/components/ChoiceList.qml
@@ -0,0 +1,52 @@
+import QtQuick 1.0
+import "../../../components" 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 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"}
+    }
+}
diff --git a/components/GroupBox.qml b/components/GroupBox.qml
new file mode 100644
index 000000000..0d45810d1
--- /dev/null
+++ b/components/GroupBox.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Item {
+    width:200
+    height:46
+
+    property alias text: styleitem.text
+    default property alias children: content.children
+    property bool checkable: false
+
+    QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            id:styleitem
+            elementType:"groupbox"
+        }
+
+        Item {
+            id:content
+            anchors.topMargin:22
+            anchors.leftMargin:6
+            anchors.fill:parent
+        }
+    }
+}
diff --git a/components/ProgressBar.qml b/components/ProgressBar.qml
new file mode 100644
index 000000000..bf29bcac9
--- /dev/null
+++ b/components/ProgressBar.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.ProgressBar {
+    id:progressbar
+
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 15).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    height: buttonHeight
+
+    background: QStyleBackground{
+        anchors.fill:parent
+        style: QStyleItem {
+            elementType:"progressbar"
+
+            // XXX: since desktop uses int instead of real, the progressbar
+            // range [0..1] must be stretched to a good precision
+            property int factor : 1000000
+
+            value:   progressbar.value * factor
+            minimum: indeterminate ? 0 : progressbar.minimumValue * factor
+            maximum: indeterminate ? 0 : progressbar.maximumValue * factor
+            enabled: progressbar.enabled
+        }
+    }
+    indeterminateProgress:null
+    progress: null
+}
+
diff --git a/components/RadioButton.qml b/components/RadioButton.qml
new file mode 100644
index 000000000..3c2c3e547
--- /dev/null
+++ b/components/RadioButton.qml
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.RadioButton{
+    id:radiobutton
+    property variant text
+    width:110
+    height:18
+
+    background: QStyleBackground {
+
+        style: QStyleItem{
+            elementType:"radiobutton"
+            sunken:pressed
+            on:checked || pressed
+            hover:containsMouse
+            text:radiobutton.text
+            enabled:radiobutton.enabled
+        }
+    }
+    checkmark: null
+}
+
diff --git a/components/ScrollArea.qml b/components/ScrollArea.qml
new file mode 100644
index 000000000..3a904ddeb
--- /dev/null
+++ b/components/ScrollArea.qml
@@ -0,0 +1,103 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+FocusScope {
+    id:scrollarea
+    width: 100
+    height: 100
+
+    property int contentMargin: 1
+    property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    property int frameWidth: styleitem.pixelMetric("defaultframewidth");
+    property int contentHeight : content.childrenRect.height
+    property int contentWidth: content.childrenRect.width
+    property alias color: flickable.color
+    property bool frame: true
+    property bool highlightOnFocus: false
+
+    default property alias children: content.children
+
+    property int contentY
+    property int contentX
+
+    property bool frameAroundContents: styleitem.styleHint("framearoundcontents")
+
+    onContentYChanged: {
+        vscrollbar.value = contentY
+    }
+
+    onContentXChanged: {
+        hscrollbar.value = contentX
+    }
+
+    QStyleBackground {
+        style: QStyleItem{
+            id:styleitem
+            elementType: frame ? "frame" : ""
+            sunken: true
+        }
+        anchors.fill: parent
+        anchors.rightMargin: (frameAroundContents && vscrollbar.visible) ? vscrollbar.width + 4 : -frameWidth
+        anchors.bottomMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth
+        anchors.topMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth
+
+        Rectangle {
+            id:flickable
+            color: "transparent"
+            anchors.fill: parent
+            anchors.margins: frame ? 2 : 0
+            clip: true
+
+            Item {
+                id: docmargins
+                anchors.fill:parent
+                anchors.margins:contentMargin
+                Item {
+                    id: content
+                    x: -scrollarea.contentX
+                    y: -scrollarea.contentY
+                }
+            }
+        }
+    }
+
+    ScrollBar {
+        id: hscrollbar
+        orientation: Qt.Horizontal
+        visible: contentWidth > flickable.width
+        maximumValue: contentWidth > flickable.width ? scrollarea.contentWidth - flickable.width : 0
+        minimumValue: 0
+        anchors.bottom: parent.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.rightMargin: { return (frame ? 1 : 0) + ( vscrollbar.visible ? __scrollbarExtent : 0) }
+        onValueChanged: contentX = value
+    }
+
+    ScrollBar {
+        id: vscrollbar
+        orientation: Qt.Vertical
+        visible: contentHeight > flickable.height
+        maximumValue: contentHeight > flickable.height ? scrollarea.contentHeight - flickable.height : 0
+        minimumValue: 0
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        anchors.bottomMargin:  { return (frame ? 1 : 0) + (hscrollbar.visible ? __scrollbarExtent : 0) }
+        onValueChanged: contentY = value
+    }
+
+    QStyleBackground {
+        z:2
+        anchors.fill:parent
+        anchors.margins:-2
+        anchors.rightMargin:-4
+        anchors.bottomMargin:-4
+        visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget")
+        style: QStyleItem {
+            id:framestyle
+            elementType:"focusframe"
+        }
+    }
+}
diff --git a/components/ScrollBar.qml b/components/ScrollBar.qml
new file mode 100644
index 000000000..ea822b62e
--- /dev/null
+++ b/components/ScrollBar.qml
@@ -0,0 +1,109 @@
+import QtQuick 1.1
+import "../../../components" as Components
+import "../plugin"
+
+MouseArea {
+    id:scrollbar
+    property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    implicitWidth:orientation == Qt.Horizontal ? 200 : __scrollbarExtent;
+    implicitHeight:orientation == Qt.Horizontal ? __scrollbarExtent : 200
+
+    property int orientation : Qt.Horizontal
+    property alias minimumValue: slider.minimumValue
+    property alias maximumValue: slider.maximumValue
+    property alias value: slider.value
+
+    property bool upPressed;
+    property bool downPressed;
+    property bool __autoincrement: false
+
+    // Update hover item
+    onEntered: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY)
+    onExited: styleitem.activeControl = "none"
+    onMouseXChanged: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY)
+    hoverEnabled:true
+
+    Timer { running: upPressed || downPressed; interval: 350 ; onTriggered: __autoincrement = true }
+    Timer { running: __autoincrement; interval: 60 ; repeat: true ;
+        onTriggered: upPressed ? decrement() : increment() }
+
+    onPressed: {
+        var control = bgitem.hitTest(mouseX,mouseY)
+        if (control == "up") {
+            upPressed = true
+        } else if (control == "down") {
+            downPressed = true
+        }
+    }
+
+    onReleased: {
+        __autoincrement = false;
+        if (upPressed) {
+            upPressed = false;
+            decrement()
+        } else if (downPressed) {
+            increment()
+            downPressed = false;
+        }
+    }
+
+    function increment() {
+        value += 30
+        if (value > maximumValue)
+            value = maximumValue
+    }
+
+    function decrement() {
+        value -= 30
+        if (value < minimumValue)
+            value = minimumValue
+    }
+
+    QStyleBackground {
+        id:bgitem
+        anchors.fill:parent
+        style: QStyleItem {
+            id:styleitem
+            elementType: "scrollbar"
+            hover: activeControl != "none"
+            activeControl: "none"
+            sunken: upPressed | downPressed
+            minimum: slider.minimumValue
+            maximum: slider.maximumValue
+            value: slider.value
+            horizontal: orientation == Qt.Horizontal
+            enabled: parent.enabled
+        }
+    }
+
+    property variant handleRect
+    function updateHandle() {
+        handleRect = bgitem.subControlRect("handle")
+        var grooveRect = bgitem.subControlRect("groove");
+        var extra = 0
+        if (orientation == Qt.Vertical) {
+            slider.anchors.topMargin = grooveRect.y + extra
+            slider.anchors.bottomMargin = height - grooveRect.y - grooveRect.height + extra
+        } else {
+            slider.anchors.leftMargin = grooveRect.x + extra
+            slider.anchors.rightMargin = width - grooveRect.x - grooveRect.width + extra
+        }
+    }
+
+    onValueChanged: updateHandle()
+    onMaximumValueChanged: updateHandle()
+    onMinimumValueChanged: updateHandle()
+    Component.onCompleted: updateHandle()
+    Components.Slider {
+        id:slider
+        anchors.fill:parent
+        orientation:scrollbar.orientation
+        leftMargin: (orientation === Qt.Horizontal) ? handleRect.width/2 : handleRect.height/2
+        rightMargin:leftMargin
+        handle: Item { width:orientation == Qt.Vertical ? handleRect.height : handleRect.width;
+                       height:orientation == Qt.Vertical ? handleRect.width : handleRect.height}
+        groove:null
+        valueIndicator:null
+        inverted:orientation != Qt.Horizontal
+    }
+}
diff --git a/components/Slider.qml b/components/Slider.qml
new file mode 100644
index 000000000..c6b9c9151
--- /dev/null
+++ b/components/Slider.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jens: ContainsMouse breaks drag functionality
+
+Components.Slider{
+    id:slider
+    minimumWidth:200
+
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 15).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    height: buttonHeight
+
+    groove: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"slider"
+            sunken: pressed
+            maximum:slider.maximumValue
+            minimum:slider.minimumValue
+            value:slider.value
+            horizontal:slider.orientation == Qt.Horizontal
+            enabled:slider.enabled
+        }
+    }
+
+    handle: null
+    valueIndicator: null
+}
diff --git a/components/SpinBox.qml b/components/SpinBox.qml
new file mode 100644
index 000000000..2db428cef
--- /dev/null
+++ b/components/SpinBox.qml
@@ -0,0 +1,91 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.SpinBox {
+    id:spinbox
+
+    property variant __upRect;
+    property variant __downRect;
+    property int __margin: (height -16)/2
+
+    // Align height with button
+    topMargin:__margin
+    bottomMargin:__margin
+
+    property int buttonHeight: edititem.sizeFromContents(100, 20).height
+    QStyleItem { id:edititem; elementType:"edit" }
+    height: buttonHeight
+    clip:false
+
+    background:
+        Item {
+        anchors.fill: parent
+        property variant __editRect
+
+        Rectangle {
+            id:editBackground
+            x: __editRect.x - 1
+            y: __editRect.y
+            width: __editRect.width
+            height: __editRect.height
+        }
+
+        Item {
+            id:focusFrame
+            anchors.fill: editBackground
+            visible:framestyle.styleHint("focuswidget")
+            QStyleBackground{
+                anchors.margins: -6
+                anchors.leftMargin: -5
+                anchors.fill: parent
+                visible:spinbox.activeFocus
+                style: QStyleItem {
+                    id:framestyle
+                    elementType:"focusframe"
+                }
+            }
+        }
+
+        function updateRect() {
+            __upRect = spinboxbg.subControlRect("up");
+            __downRect = spinboxbg.subControlRect("down");
+            __editRect = spinboxbg.subControlRect("edit");
+        }
+
+        Component.onCompleted:updateRect()
+        onWidthChanged:updateRect()
+        onHeightChanged:updateRect()
+
+        QStyleBackground {
+            id:spinboxbg
+            anchors.fill:parent
+            style: QStyleItem {
+                id: styleitem
+                elementType: "spinbox"
+                sunken: downPressed | upPressed
+                hover: containsMouse
+                focus: spinbox.activeFocus
+                enabled: spinbox.enabled
+                value: (upPressed? 1 : 0)           |
+                        (downPressed== 1 ? 1<<1 : 0) |
+                        (upEnabled? (1<<2) : 0)      |
+                        (downEnabled == 1 ? (1<<3) : 0)
+            }
+        }
+    }
+
+    up: Item {
+        x: __upRect.x
+        y: __upRect.y
+        width: __upRect.width
+        height: __upRect.height
+    }
+
+    down: Item {
+        x: __downRect.x
+        y: __downRect.y
+        width: __downRect.width
+        height: __downRect.height
+    }
+}
diff --git a/components/Switch.qml b/components/Switch.qml
new file mode 100644
index 000000000..b82817c9f
--- /dev/null
+++ b/components/Switch.qml
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Switch {
+    id:widget
+    minimumWidth:100
+    minimumHeight:30
+
+    groove:QStyleItem {
+        elementType:"edit"
+        sunken: true
+    }
+
+    handle: QStyleItem {
+        elementType:"button"
+        width:widget.width/2
+        height:widget.height-4
+        hover:containsMouse
+    }
+}
+
diff --git a/components/Tab.qml b/components/Tab.qml
new file mode 100644
index 000000000..e258185ba
--- /dev/null
+++ b/components/Tab.qml
@@ -0,0 +1,7 @@
+import Qt 4.7
+
+Item {
+    id:tab
+    anchors.fill:parent
+    property string title
+}
diff --git a/components/TabBar.qml b/components/TabBar.qml
new file mode 100644
index 000000000..2d891256f
--- /dev/null
+++ b/components/TabBar.qml
@@ -0,0 +1,90 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+
+Item {
+    id: tabbar
+    property int tabHeight: styleitem.sizeFromContents(100, 24).height
+    height: tabHeight
+
+    property Item tabFrame
+    onTabFrameChanged:parent = tabFrame
+    visible: tabFrame ? tabFrame.tabsVisible : true
+    property int __overlap : styleitem.pixelMetric("tabvshift");
+    property string position: tabFrame ? tabFrame.position : "North"
+    property string tabBarAlignment: styleitem.styleHint("tabbaralignment");
+    property int tabOverlap: styleitem.pixelMetric("taboverlap");
+
+    function tab(index) {
+        for (var i = 0; i < tabrow.children.length; ++i) {
+            if (tabrow.children[i].tabindex == index) {
+                return tabrow.children[i]
+            }
+        }
+        return null;
+    }
+
+    QStyleItem {
+        id:styleitem
+        elementType: "tab"
+        text: "generic"
+    }
+
+    Row {
+        id:tabrow
+        states:
+        State {
+            when: tabBarAlignment == "center"
+            name: "centered"
+            AnchorChanges {
+                target:tabrow
+                anchors.horizontalCenter: tabbar.horizontalCenter
+            }
+        }
+        Repeater {
+            id:repeater
+            model: tabFrame ? tabFrame.tabs.length : null
+            delegate: Item {
+                id:tab
+                property int tabindex: index
+                property bool selected : tabFrame.current == index
+                width: textitem.width + 42
+                height: tabHeight
+                z: selected ? 1 : -1
+
+                QStyleBackground {
+                    style: QStyleItem {
+                        id:style
+                        elementType: "tab"
+                        selected: tab.selected
+                        text: tabbar.position
+
+                        activeControl: tabFrame.count == 1 ?
+                                           "only" :
+                        index == 0 ? "beginning" :
+                            index == tabFrame.count-1 ? "end" : "middle"
+                    }
+                    anchors.leftMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle" || style.activeControl == "end")
+                                        && tab.selected ? -__overlap : 0)
+
+                    anchors.rightMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle"  || style.activeControl == "beginning")
+                                         && tab.selected ? -__overlap : 0)
+                    anchors.fill:parent
+                }
+
+                Text {
+                    id:textitem
+                    anchors.centerIn:parent
+                    text:  tabFrame.tabs[index].title
+                    elide: Text.ElideRight
+                }
+
+                MouseArea {
+                    anchors.fill: parent
+                    onPressed: tabFrame.current = index
+                }
+            }
+        }
+    }
+}
diff --git a/components/TabFrame.qml b/components/TabFrame.qml
new file mode 100644
index 000000000..01896e753
--- /dev/null
+++ b/components/TabFrame.qml
@@ -0,0 +1,72 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Item{
+    id: tabWidget
+    width:100
+    height:100
+    property TabBar tabbar
+    property int current: 0
+    property int count: stack.children.length
+    property bool frame:true
+    property bool tabsVisible: true
+    property string position: "North"
+    default property alias tabs : stack.children
+
+    onCurrentChanged: __setOpacities()
+    Component.onCompleted: __setOpacities()
+    onTabbarChanged: {
+        tabbar.tabFrame = tabWidget
+        tabbar.anchors.top = tabWidget.top
+        tabbar.anchors.left = tabWidget.left
+        tabbar.anchors.right = tabWidget.right
+    }
+
+    property int __baseOverlap : style.pixelMetric("tabbaseoverlap");
+    function __setOpacities() {
+        for (var i = 0; i < stack.children.length; ++i) {
+            stack.children[i].opacity = (i == current ? 1 : 0)
+        }
+    }
+
+    QStyleBackground {
+        id: frame
+        z:-1
+        style: QStyleItem {
+            id:style
+            elementType: "tabframe"
+            text: position
+            value: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).x : 0
+            minimum: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).width : 0
+        }
+        anchors.fill:parent
+        Item {
+            id:stack
+            anchors.fill:parent
+            anchors.margins: frame ? 2 : 0
+        }
+        anchors.topMargin: tabbar && tabsVisible && position == "North" ? tabbar.height - __baseOverlap : 0
+
+        states: [
+            State {
+                name: "South"
+                when: position == "South" && tabbar!= undefined
+                PropertyChanges {
+                    target: frame
+                    anchors.topMargin: 0
+                    anchors.bottomMargin: tabbar ? tabbar.height - __baseOverlap: 0
+                }
+                PropertyChanges {
+                    target: tabbar
+                    anchors.topMargin: -__baseOverlap
+                }
+                AnchorChanges {
+                    target: tabbar
+                    anchors.top: frame.bottom
+                    anchors.bottom: undefined
+                }
+            }
+        ]
+    }
+}
diff --git a/components/TextArea.qml b/components/TextArea.qml
new file mode 100644
index 000000000..93ad8f3d9
--- /dev/null
+++ b/components/TextArea.qml
@@ -0,0 +1,44 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.TextArea {
+    id:textarea
+    leftMargin:12
+    rightMargin:12
+    minimumWidth:200
+    desktopBehavior:true
+    placeholderText:""
+    clip:false
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 14).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    minimumHeight: buttonHeight
+
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"edit"
+            sunken:true
+            focus:textarea.activeFocus
+        }
+    }
+
+    Item{
+        id:focusFrame
+        anchors.fill: textarea
+        parent:textarea.parent
+        visible:framestyle.styleHint("focuswidget")
+        QStyleBackground{
+            anchors.margins: -2
+            anchors.rightMargin:-4
+            anchors.bottomMargin:-4
+            anchors.fill: parent
+            visible:textarea.activeFocus
+            style: QStyleItem {
+                id:framestyle
+                elementType:"focusframe"
+            }
+        }
+    }
+}
diff --git a/components/TextField.qml b/components/TextField.qml
new file mode 100644
index 000000000..260584e95
--- /dev/null
+++ b/components/TextField.qml
@@ -0,0 +1,52 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.TextField {
+    id:textfield
+    minimumWidth:200
+    desktopBehavior:true
+    placeholderText:""
+    topMargin:2
+    bottomMargin:2
+    leftMargin:6
+    rightMargin:6
+    width:200
+    height: editItem.sizeFromContents(100, 20).height
+    clip:false
+
+    QStyleItem {
+        id:editItem
+        elementType:"edit"
+        sunken:true
+        focus:textfield.activeFocus
+        hover:containsMouse
+    }
+
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"edit"
+            sunken:true
+            focus:textfield.activeFocus
+        }
+    }
+
+    Item{
+        id:focusFrame
+        anchors.fill: textfield
+        parent:textfield
+        visible:framestyle.styleHint("focuswidget")
+        QStyleBackground{
+            anchors.margins: -2
+            anchors.rightMargin:-4
+            anchors.bottomMargin:-4
+            anchors.fill: parent
+            visible:textfield.activeFocus
+            style: QStyleItem {
+                id:framestyle
+                elementType:"focusframe"
+            }
+        }
+    }
+}
diff --git a/components/TextScrollArea.qml b/components/TextScrollArea.qml
new file mode 100644
index 000000000..2a7deab68
--- /dev/null
+++ b/components/TextScrollArea.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+ScrollArea {
+    id:area
+    color: "white"
+    width: 280
+    height: 120
+    contentWidth: 200
+
+    property alias text: edit.text
+    property alias wrapMode: edit.wrapMode
+    highlightOnFocus: true
+
+    TextEdit {
+        id: edit
+        text: loremIpsum + loremIpsum;
+        wrapMode: TextEdit.WordWrap;
+        width: area.contentWidth
+        selectByMouse:true
+
+        // keep textcursor within scrollarea
+        onCursorRectangleChanged:
+            if (cursorRectangle.y >= area.contentY + area.height - 1.5*cursorRectangle.height)
+                area.contentY = cursorRectangle.y - area.height + 1.5*cursorRectangle.height
+            else if (cursorRectangle.y < area.contentY)
+                area.contentY = cursorRectangle.y
+
+    }
+}
diff --git a/components/ToolBar.qml b/components/ToolBar.qml
new file mode 100644
index 000000000..ce61382ee
--- /dev/null
+++ b/components/ToolBar.qml
@@ -0,0 +1,12 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+QStyleBackground {
+    id:styleitem
+    width:200
+    height:60
+
+    style: QStyleItem{elementType:"toolbar"}
+}
+
diff --git a/components/ToolButton.qml b/components/ToolButton.qml
new file mode 100644
index 000000000..98b2dfebf
--- /dev/null
+++ b/components/ToolButton.qml
@@ -0,0 +1,18 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Button {
+    id:button
+    minimumWidth:30
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem {
+            elementType: "toolbutton"
+            on: pressed | checked
+            sunken: pressed
+            raised: containsMouse
+            hover: containsMouse
+        }
+    }
+}
diff --git a/components/custom/BasicButton.qml b/components/custom/BasicButton.qml
new file mode 100644
index 000000000..1116f0b01
--- /dev/null
+++ b/components/custom/BasicButton.qml
@@ -0,0 +1,44 @@
+import QtQuick 1.1
+import "./behaviors"    // ButtonBehavior
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: button
+
+    signal clicked
+    property alias pressed: behavior.pressed
+    property alias containsMouse: behavior.containsMouse
+    property alias checkable: behavior.checkable  // button toggles between checked and !checked
+    property alias checked: behavior.checked
+
+    property Component background: defaultStyle.background
+
+    property color backgroundColor: syspal.button
+    property color textColor: syspal.text;
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    // implementation
+
+    property string __position: "only"
+    implicitWidth: Math.max(minimumWidth, backgroundLoader.item.width)
+    implicitHeight: Math.max(minimumHeight, backgroundLoader.item.height)
+
+    Loader {
+        id: backgroundLoader
+        anchors.fill: parent
+        sourceComponent: background
+        property alias styledItem: button
+        property alias position: button.__position
+    }
+
+    ButtonBehavior {
+        id: behavior
+        anchors.fill: parent
+        onClicked: button.clicked()
+    }
+
+    DefaultStyles.BasicButtonStyle { id: defaultStyle }
+    SystemPalette { id: syspal }
+}
diff --git a/components/custom/BusyIndicator.qml b/components/custom/BusyIndicator.qml
new file mode 100644
index 000000000..00b12ed3f
--- /dev/null
+++ b/components/custom/BusyIndicator.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: busyIndicator
+
+    // Common API:
+    property bool running: true
+
+    width: backgroundComponent.item.width;
+    height: backgroundComponent.item.height;
+
+    property Component background: defaultStyle.background
+
+    Loader {
+        id: backgroundComponent
+        property bool running: busyIndicator.opacity > 0 &&
+                               busyIndicator.visible &&
+                               busyIndicator.running
+//        onRunningChanged: print("Running: " + running)
+        anchors.fill: parent
+        sourceComponent: background
+
+    }
+
+    DefaultStyles.BusyIndicatorStyle { id: defaultStyle }
+}
diff --git a/components/custom/Button.qml b/components/custom/Button.qml
new file mode 100644
index 000000000..1bcd8335e
--- /dev/null
+++ b/components/custom/Button.qml
@@ -0,0 +1,39 @@
+import QtQuick 1.1
+import "./styles/default" as DefaultStyles
+
+BasicButton {
+    id: button
+
+    property string text
+    property url iconSource
+
+    property Component label: defaultStyle.label
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int topMargin: defaultStyle.topMargin
+    property int rightMargin: defaultStyle.rightMargin
+    property int bottomMargin: defaultStyle.bottomMargin
+
+    // implementation
+
+    implicitWidth: Math.max(minimumWidth, labelLoader.item.implicitWidth + leftMargin + rightMargin)
+    implicitHeight: Math.max(minimumHeight, labelLoader.item.implicitHeight + topMargin + bottomMargin)
+
+    minimumWidth: defaultStyle.minimumWidth
+    minimumHeight: defaultStyle.minimumHeight
+
+    background: defaultStyle.background
+
+    Loader {
+        id: labelLoader
+        anchors.fill: parent
+        anchors.leftMargin: leftMargin
+        anchors.rightMargin: rightMargin
+        anchors.topMargin: topMargin
+        anchors.bottomMargin: bottomMargin
+        property alias styledItem: button
+        sourceComponent: label
+    }
+
+    DefaultStyles.ButtonStyle { id: defaultStyle }
+}
diff --git a/components/custom/ButtonBlock.qml b/components/custom/ButtonBlock.qml
new file mode 100644
index 000000000..999d3dd06
--- /dev/null
+++ b/components/custom/ButtonBlock.qml
@@ -0,0 +1,216 @@
+import QtQuick 1.0
+import "./behaviors"    // ButtonBehavior
+import "./visuals"      // AdjoiningVisual
+import "./styles/default" as DefaultStyles
+
+// KNOWN ISSUES
+// 1) When switching between horizontal and vertical orientation after block has been created, the Grid's move
+//    transition is called *before* the grid item's have actually moved, resulting in incorrect "adjoins" states
+// 2) Can't make items in vertical groups all the same width without access to their implicitWidth, see QTBUG-14957
+// 3) Should be generalized into JoinedGroup and ButtonBlock made a specialization.
+// 4) ExclusiveSelection support missing
+
+// NOTES
+// 1) The ButtonBlock implementation has no ultimate dependency on AdjoiningVisual, and can therefor be made to work
+//    with any Component for the item instances. The use of AdjoiningVisual is only for simplifying the implementation
+//    and styling of the items in the block. The property defining how an item in the block should be joinged with its
+//    neighbours is "adjoins" which the ButtonBlock "attaches" to the items in the block (i.e. defines in their
+//    look-up scope) which means the "button" instances does not need to define this property, only read it to draw
+//    their border appropriately. This "adjoins" property is a *completely* separate concept from the AdjoiningVisual.
+//    I.e. the coupling between the ButtonGroup and the "button" elements making up the group is the weakest possible.
+
+
+Item {
+    id: buttonBlock
+
+    property alias model: repeater.model
+    property variant bindings: {"text":"text", "iconSource":"iconSource", "enabled":"enabled", "opacity":"opacity"}
+
+    property Component buttonBackground: defaultStyle.background
+    property Component buttonLabel: defaultStyle.label
+
+    property color backgroundColor: syspal.button
+    property color textColor: syspal.text;
+
+    property int orientation: Qt.Horizontal
+    signal clicked(int index)
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int topMargin: defaultStyle.topMargin
+    property int rightMargin: defaultStyle.rightMargin
+    property int bottomMargin: defaultStyle.bottomMargin
+
+    width: grid.width
+    height: grid.height
+
+    Grid {
+        id: grid
+        columns: orientation == Qt.Vertical ? 1 : model.count
+        anchors.centerIn: parent
+        property int widestItemWidth: 0
+        property int talestItemHeight: 0
+
+        move: Transition {  //mm seems "move" transition is not always called after items has been moved
+            ScriptAction { script: {
+                    if(orientation == Qt.Horizontal) {
+                        grid.leftmostVisibleIndex = grid.__leftmostVisibleIndex();
+                        grid.rightmostVisibleIndex = grid.__rightmostVisibleIndex();
+                    } else {
+                        grid.topmostVisibleIndex = grid.__topmostVisibleIndex();
+                        grid.bottommostVisibleIndex = grid.__bottommostVisibleIndex();
+                    }
+                }
+            }
+        }
+
+        property int leftmostVisibleIndex
+        function __leftmostVisibleIndex() {
+            var leftmostVisibleIndex = 0;
+            var leftmostItemX = 10000000;
+            for(var i = 0; i < children.length; i++) {
+                var child = children[i];
+                if(child.x < leftmostItemX && child.opacity > 0) {
+                    leftmostItemX = child.x;
+                    leftmostVisibleIndex = i;
+                }
+            }
+            return leftmostVisibleIndex;
+        }
+
+        property int rightmostVisibleIndex
+        function __rightmostVisibleIndex() {
+            var rightmostVisibleIndex = 0;
+            var rightmostItemX = 0;
+            for(var i = 0; i < children.length; i++) {
+                var child = children[i];
+//mm                print("rightmost child? at: " + child.x + "," + child.y)
+                if(child.x > rightmostItemX && child.opacity > 0) {
+                    rightmostItemX = child.x;
+                    rightmostVisibleIndex = i;
+                }
+            }
+            return rightmostVisibleIndex;
+        }
+
+        property int topmostVisibleIndex
+        function __topmostVisibleIndex() {
+            var topmostVisibleIndex = 0;
+            var topmostItemY = 10000000;
+            for(var i = 0; i < children.length; i++) {
+                var child = children[i];
+                if(child.y < topmostItemY && child.opacity > 0) {
+                    topmostItemY = child.y;
+                    topmostVisibleIndex = i;
+                }
+            }
+            return topmostVisibleIndex;
+        }
+
+        property int bottommostVisibleIndex
+        function __bottommostVisibleIndex() {
+            var bottommostVisibleIndex = 0;
+            var bottommostItemY = 0;
+            for(var i = 0; i < children.length; i++) {
+                var child = children[i];
+//mm                print("bottommost child? at: " + child.x + "," + child.y)
+                if(child.y > bottommostItemY && child.opacity > 0) {
+                    bottommostItemY = child.y;
+                    bottommostVisibleIndex = i;
+                }
+            }
+            return bottommostVisibleIndex;
+        }
+
+        Repeater {
+            id: repeater
+            delegate: AdjoiningVisual {
+                id: blockButton
+                styledItem: blockButton
+                styling: buttonBackground
+
+                property alias pressed: behavior.pressed
+                property alias containsMouse: behavior.containsMouse
+                property alias checkable: behavior.checkable  // button toggles between checked and !checked
+                property alias checked: behavior.checked
+
+                property string text
+                property url iconSource
+                property color textColor: buttonBlock.textColor
+                property color backgroundColor: buttonBlock.backgroundColor
+
+                Component.onCompleted: {
+                    // Create the Binding objects defined by the ButtonBlock's "bindings" map property to allow
+                    // the properties of the buttons to be bound to properties in the model with different names
+
+                    if (bindings == undefined) // jb : bindings is undefined on Mac
+                        return;
+                    var keys = Object.keys(buttonBlock.bindings);
+                    for(var i = 0; i < keys.length; i++) {
+                        var key = keys[i];
+                        var bindingComponent =
+                                'import QtQuick 1.0;' +
+                                'Binding {' +
+                                '    target: blockButton;' +
+                                '    property: "' + key + '";' +
+                                '    value: buttonBlock.model.get(' + index + ').' + bindings[key] + ';' +
+                                '}';
+                        Qt.createQmlObject(bindingComponent, blockButton);    //mm do we ever need to explicitly delete these?
+                    }
+
+                    // Find the widest/talest item to make all buttons the same width/height
+                    if(buttonBlock.orientation == Qt.Vertical)    //mm Can't make this work without QTBUG-14957
+                        grid.widestItemWidth = Math.max(grid.widestItemWidth, width);
+                    else
+                        grid.talestItemHeight = Math.max(grid.talestItemHeight, height);
+                }
+
+                ButtonBehavior {
+                    id: behavior
+                    anchors.fill: parent
+                    onClicked: buttonBlock.clicked(index)
+                }
+
+                property int adjoins
+                adjoins: {   //mm see QTBUG-14987
+                    var adjoins;
+                    if(orientation == Qt.Horizontal) {
+                        adjoins = 0x1|0x2;  // left and right
+                        if(index == grid.leftmostVisibleIndex) adjoins &= ~0x1;   // not left
+                        if(index == grid.rightmostVisibleIndex) adjoins &= ~0x2;  // not right
+                    } else {
+                        adjoins = 0x4|0x8;  // top and bottom
+                        if(index == grid.topmostVisibleIndex) adjoins &= ~0x4;    // not top
+                        if(index == grid.bottommostVisibleIndex) adjoins &= ~0x8; // not bottom
+                    }
+                    return adjoins;
+                }
+
+
+               // width: orientation == Qt.Vertical ? grid.widestItemWidth : item.width
+               // height: orientation == Qt.Vertical ? item.height : grid.talestItemHeight
+                property int minimumWidth: defaultStyle.minimumWidth
+                property int minimumHeight: defaultStyle.minimumHeight
+
+                width: Math.max(minimumWidth,
+                                labelComponent.item.width + leftMargin + rightMargin)
+                height: Math.max(minimumHeight,
+                                 labelComponent.item.height + topMargin + bottomMargin)
+
+                Loader {
+                    id: labelComponent
+                    property variant styledItem: blockButton
+                    anchors.fill: parent
+                    anchors.leftMargin: leftMargin
+                    anchors.rightMargin: rightMargin
+                    anchors.topMargin: topMargin
+                    anchors.bottomMargin: bottomMargin
+                    sourceComponent: buttonLabel
+                }
+
+            }
+        }
+    }
+
+    SystemPalette { id: syspal; colorGroup: enabled ? SystemPalette.Active : SystemPalette.Disabled }
+    DefaultStyles.ButtonBlockStyle { id: defaultStyle }
+}
diff --git a/components/custom/ButtonColumn.qml b/components/custom/ButtonColumn.qml
new file mode 100644
index 000000000..8d63a855c
--- /dev/null
+++ b/components/custom/ButtonColumn.qml
@@ -0,0 +1,44 @@
+import Qt 4.7
+import "ButtonGroup.js" as Behavior
+
+/*
+   Class: ButtonColumn
+   A ButtonColumn allows you to group Buttons in a column. It provides a selection-behavior as well.
+
+   Note: This component don't support the enabled property.
+   If you need to disable it you should disable all the buttons inside it.
+
+   <code>
+       ButtonColumn {
+           Button { text: "Top" }
+           Button { text: "Bottom" }
+       }
+   </code>
+*/
+Column {
+    id: root
+
+    /*
+     * Property: exclusive
+     * [bool=true] Specifies the grouping behavior. If enabled, the checked property on buttons contained
+     * in the group will be exclusive.
+     *
+     * Note that a button in an exclusive group will allways be checkable
+     */
+    property bool exclusive: true
+
+    /*
+     * Property: checkedButton
+     * [string] Contains the last checked Button.
+     */
+    property Item checkedButton;
+
+    Component.onCompleted: {
+        Behavior.create(root, {direction: Qt.Vertical});
+    }
+
+    Component.onDestruction: {
+        Behavior.destroy();
+    }
+
+}
diff --git a/components/custom/ButtonGroup.js b/components/custom/ButtonGroup.js
new file mode 100644
index 000000000..f2d000029
--- /dev/null
+++ b/components/custom/ButtonGroup.js
@@ -0,0 +1,127 @@
+var self;
+var clickHandlers = [];
+var visibleButtons = [];
+var nonVisibleButtons = [];
+var direction;
+var exclusive;
+
+function create(that, options) {
+    self = that;
+    direction = options.direction || Qt.Horizontal;
+    exclusive = self.exclusive|| options.exclusive;
+    self.childrenChanged.connect(rebuild);
+//    self.widthChanged.connect(resizeChildren);
+    build();
+}
+
+function isButton(item) {
+    if (item && item["__position"] !== undefined)
+        return true;
+    return false;
+}
+
+function hasChecked(item) {
+    if (item && item["checked"] !== undefined)
+        return true;
+    return false;
+}
+
+function destroy() {
+    self.childrenChanged.disconnect(rebuild);
+//    self.widthChanged.disconnect(resizeChildren);
+    cleanup();
+}
+
+function build() {
+    visibleButtons = [];
+    nonVisibleButtons = [];
+
+    for (var i = 0, item; (item = self.children[i]); i++) {
+        if (!hasChecked(item))
+            continue;
+
+        item.visibleChanged.connect(rebuild); // Not optimal, but hardly a bottleneck in your app
+        if (!item.visible) {
+            nonVisibleButtons.push(item);
+            continue;
+        }
+        visibleButtons.push(item);
+
+        if (exclusive && hasChecked(item)) {
+            if (item["checkable"]!==undefined) {
+                item.checkable = true;
+            }
+            clickHandlers[i] = checkExclusive(item);
+            item.clicked.connect(clickHandlers[i]);
+        }
+    }
+
+    if (self.checkedButton && !self.checkedButton.visible)
+        self.checkedButton = undefined;
+
+    var nrButtons = visibleButtons.length;
+    if (nrButtons == 0)
+        return;
+
+    if (nrButtons == 1) {
+        finishButton(visibleButtons[0], "only");
+    } else {
+        finishButton(visibleButtons[0], direction == Qt.Horizontal ? "leftmost" : "top");
+        for (var i = 1; i < nrButtons - 1; i++)
+            finishButton(visibleButtons[i], direction == Qt.Horizontal ? "h_middle": "v_middle");
+        finishButton(visibleButtons[nrButtons - 1], direction == Qt.Horizontal ? "rightmost" : "bottom");
+    }
+}
+
+function finishButton(button, position) {
+    if (isButton(button)) {
+        button.__position = position;
+        if (direction == Qt.Vertical) {
+            button.anchors.left = self.left
+            button.anchors.right = self.right
+        }
+    }
+}
+
+function cleanup() {
+    visibleButtons.forEach(function(item, i) {
+        if (clickHandlers[i])
+            item.clicked.disconnect(clickHandlers[i]);
+        item.visibleChanged.disconnect(rebuild);
+    });
+    clickHandlers = [];
+
+    nonVisibleButtons.forEach(function(item, i) {
+        item.visibleChanged.disconnect(rebuild);
+    });
+}
+
+function rebuild() {
+    cleanup();
+    build();
+}
+
+function resizeChildren() {
+    if (direction != Qt.Horizontal)
+        return;
+
+    var extraPixels = self.width % visibleButtons;
+    var buttonSize = (self.width - extraPixels) / visibleButtons;
+    visibleButtons.forEach(function(item, i) {
+        if (!item || !item.visible)
+            return;
+        item.width = buttonSize + (extraPixels > 0 ? 1 : 0);
+        if (extraPixels > 0)
+            extraPixels--;
+    });
+}
+
+function checkExclusive(item) {
+    var button = item;
+    return function() {
+        for (var i = 0, ref; (ref = visibleButtons[i]); i++) {
+            ref.checked = button === ref;
+        }
+        self.checkedButton = button;
+    }
+}
diff --git a/components/custom/ButtonRow.qml b/components/custom/ButtonRow.qml
new file mode 100644
index 000000000..7c2d3ea7a
--- /dev/null
+++ b/components/custom/ButtonRow.qml
@@ -0,0 +1,43 @@
+import Qt 4.7
+import "ButtonGroup.js" as Behavior
+
+/*
+   Class: ButtonRow
+   A ButtonRow allows you to group Buttons in a row. It provides a selection-behavior as well.
+
+   Note: This component don't support the enabled property.
+   If you need to disable it you should disable all the buttons inside it.
+
+   <code>
+       ButtonRow {
+           Button { text: "Left" }
+           Button { text: "Right" }
+       }
+   </code>
+*/
+Row {
+    id: root
+
+    /*
+     * Property: exclusive
+     * [bool=true] Specifies the grouping behavior. If enabled, the checked property on buttons contained
+     * in the group will be exclusive.
+     *
+     * Note that a button in an exclusive group will allways be checkable
+     */
+    property bool exclusive: true
+
+    /*
+     * Property: checkedButton
+     * [string] Contains the last checked Button.
+     */
+    property Item checkedButton;
+
+    Component.onCompleted: {
+        Behavior.create(root, {direction: Qt.Horizontal});
+    }
+
+    Component.onDestruction: {
+        Behavior.destroy();
+    }
+}
diff --git a/components/custom/CheckBox.qml b/components/custom/CheckBox.qml
new file mode 100644
index 000000000..e8b865564
--- /dev/null
+++ b/components/custom/CheckBox.qml
@@ -0,0 +1,49 @@
+import QtQuick 1.1
+import "./behaviors"
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: checkBox
+
+    signal clicked
+    property alias pressed: behavior.pressed
+    property alias checked: behavior.checked
+    property alias containsMouse: behavior.containsMouse
+
+    property Component background: defaultStyle.background
+    property Component checkmark: defaultStyle.checkmark
+
+    property color backgroundColor: syspal.base
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    // implementation
+
+    implicitWidth: minimumWidth
+    implicitHeight: minimumHeight
+
+    Loader {
+        id: backgroundLoader
+        anchors.fill: parent
+        property alias styledItem: checkBox
+        sourceComponent: background
+    }
+
+    Loader {
+        id: checkmarkLoader
+        anchors.centerIn: parent
+        property alias styledItem: checkBox
+        sourceComponent: checkmark
+    }
+
+    ButtonBehavior {
+        id: behavior
+        anchors.fill: parent
+        checkable: true
+        onClicked: checkBox.clicked()
+    }
+
+    DefaultStyles.CheckBoxStyle { id: defaultStyle }
+    SystemPalette { id: syspal }
+}
diff --git a/components/custom/ChoiceList.qml b/components/custom/ChoiceList.qml
new file mode 100644
index 000000000..8c5ca81be
--- /dev/null
+++ b/components/custom/ChoiceList.qml
@@ -0,0 +1,85 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+import "./private" as Private //  for ChoiceListPopup
+
+// KNOWN ISSUES
+// 1) Popout list does not have a scrollbar/scroll indicator or similar
+// 2) The ChoiceListPopup should ff dynamically loaded, to support radically different implementations
+// 3) Mouse wheel scroll events not handled by the popout ListView (see QTBUG-7369)
+// 4) Support for configurable bindings between model's and ChoiceList's properties similar to ButtonBlock's is missing
+
+Item {
+    id: choiceList
+
+    property alias model: popup.model
+    property int currentIndex: popup.currentIndex
+
+    property alias containsMouse: mouseArea.containsMouse   //mm needed?
+    property bool pressed: false    //mm needed?
+
+    property color textColor: syspal.text
+    property color backgroundColor: syspal.button
+
+    property Component background: defaultStyle.background
+    property Component label: defaultStyle.label
+    property Component listItem: defaultStyle.listItem
+    property Component popupFrame: defaultStyle.popupFrame
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int topMargin: defaultStyle.topMargin
+    property int rightMargin: defaultStyle.rightMargin
+    property int bottomMargin: defaultStyle.bottomMargin
+
+    property int labelWidth: labelComponent.item.width
+    property int labelHeight: labelComponent.item.height
+
+    width: Math.max(minimumWidth,
+                    labelComponent.item.width + leftMargin + rightMargin)
+    height: Math.max(minimumHeight,
+                     labelComponent.item.height + topMargin + bottomMargin)
+
+    // Implementation
+
+    SystemPalette { id: syspal }
+    Loader {
+        property alias styledItem: choiceList
+        sourceComponent: background
+        anchors.fill: parent
+    }
+
+    Loader {
+        id: labelComponent
+        property alias model: popup.model
+        anchors.fill: parent
+        anchors.leftMargin: leftMargin
+        anchors.rightMargin: rightMargin
+        anchors.topMargin: topMargin
+        anchors.bottomMargin: bottomMargin
+        sourceComponent: label
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+        drag.target: Item {}    // disable dragging in case ChoiceList is on a Flickable
+        onPressed: {
+            choiceList.pressed = true;
+            popup.togglePopup();
+
+        }
+        onReleased: choiceList.pressed = false
+        onCanceled: choiceList.pressed = false    // mouse stolen e.g. by Flickable
+    }
+
+    Private.ChoiceListPopup {
+        id: popup
+        listItem: choiceList.listItem
+        popupFrame: choiceList.popupFrame
+    }
+
+    DefaultStyles.ChoiceListStyle { id: defaultStyle }
+}
diff --git a/components/custom/ProgressBar.qml b/components/custom/ProgressBar.qml
new file mode 100644
index 000000000..fadbbc5e0
--- /dev/null
+++ b/components/custom/ProgressBar.qml
@@ -0,0 +1,80 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: progressBar
+    SystemPalette{id:syspal}
+
+    property real value: 0
+    property real minimumValue: 0
+    property real maximumValue: 1
+    property bool indeterminate: false
+
+    property color backgroundColor: syspal.base
+    property color progressColor: syspal.highlight
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int topMargin: defaultStyle.topMargin
+    property int rightMargin: defaultStyle.rightMargin
+    property int bottomMargin: defaultStyle.bottomMargin
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    width: minimumWidth
+    height: minimumHeight
+
+    property Component background: defaultStyle.background
+    property Component progress: defaultStyle.progress
+    property Component indeterminateProgress: defaultStyle.indeterminateProgress
+
+    Loader {
+        id: groove
+        property alias indeterminate:progressBar.indeterminate
+        property alias value:progressBar.value
+        property alias maximumValue:progressBar.maximumValue
+        property alias minimumValue:progressBar.minimumValue
+
+        sourceComponent: background
+        anchors.fill: parent
+    }
+
+    Item {
+        anchors.fill: parent
+        anchors.leftMargin: leftMargin
+        anchors.rightMargin: rightMargin
+        anchors.topMargin: topMargin
+        anchors.bottomMargin: bottomMargin
+
+        Loader {
+            id: progressComponent
+            property alias styledItem: progressBar
+            property alias indeterminate:progressBar.indeterminate
+            property alias value:progressBar.value
+            property alias maximumValue:progressBar.maximumValue
+            property alias minimumValue:progressBar.minimumValue
+            property real complete: (value-minimumValue)/(maximumValue-minimumValue)
+
+            opacity: !indeterminate && value > 0 ? 1 : 0
+            width: Math.round((progressBar.width-leftMargin-rightMargin)*(complete))
+            height: progressBar.height-topMargin-bottomMargin
+            anchors.left:parent.left
+            sourceComponent: progressBar.progress
+        }
+
+        Loader {
+            id: indeterminateComponent
+            property alias styledItem: progressBar
+            property alias indeterminate:progressBar.indeterminate
+            property alias value:progressBar.value
+            property alias maximumValue:progressBar.maximumValue
+            property alias minimumValue:progressBar.minimumValue
+
+            opacity: indeterminate ? 1 : 0
+            anchors.fill: parent
+            sourceComponent: indeterminateProgress
+        }
+    }
+
+    DefaultStyles.ProgressBarStyle { id: defaultStyle }
+}
diff --git a/components/custom/RadioButton.qml b/components/custom/RadioButton.qml
new file mode 100644
index 000000000..f89f2773c
--- /dev/null
+++ b/components/custom/RadioButton.qml
@@ -0,0 +1,13 @@
+import QtQuick 1.1
+import "./styles/default" as DefaultStyles
+
+CheckBox {
+    id: radioButton
+
+    // implementation
+
+    checkmark: defaultStyle.checkmark
+    background: defaultStyle.background
+
+    DefaultStyles.RadioButtonStyle { id: defaultStyle}
+}
diff --git a/components/custom/ScrollDecorator.qml b/components/custom/ScrollDecorator.qml
new file mode 100644
index 000000000..e61a16d20
--- /dev/null
+++ b/components/custom/ScrollDecorator.qml
@@ -0,0 +1,20 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: scrollDecorator
+
+    property Flickable flickableItem
+
+    anchors.fill: parent
+
+    ScrollIndicator {
+        horizontal: true
+        scrollItem: scrollDecorator.flickableItem
+    }
+
+    ScrollIndicator {
+        horizontal: false
+        scrollItem: scrollDecorator.flickableItem
+    }
+}
diff --git a/components/custom/ScrollIndicator.qml b/components/custom/ScrollIndicator.qml
new file mode 100644
index 000000000..cba1dba81
--- /dev/null
+++ b/components/custom/ScrollIndicator.qml
@@ -0,0 +1,56 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: scrollIndicator
+
+    property Flickable scrollItem
+    property bool horizontal: false
+
+    property Component content: defaultStyle.content
+
+    //private
+    anchors.left: horizontal ? parent.left : undefined
+    anchors.right: parent.right
+    anchors.top: horizontal ? undefined : parent.top
+    anchors.bottom: parent.bottom
+    width:  horizontal ? parent.width : defaultStyle.minimumWidth
+    height: horizontal ? defaultStyle.minimumWidth : parent.height
+
+    opacity: (horizontal ? scrollItem.movingHorizontally : scrollItem.movingVertically) ? 1 : 0
+    Behavior on opacity { NumberAnimation { duration: 100 } }
+
+    Item {
+        id: ratationContainer
+
+        anchors.centerIn: parent
+        rotation: horizontal ? -90 : 0
+        width: horizontal ? scrollIndicator.height : scrollIndicator.width  // rotate width and heigh back
+        height: horizontal ? scrollIndicator.width : scrollIndicator.height
+
+        property variant visibleArea: scrollItem.visibleArea
+        property real scrollItemSize: horizontal ? scrollItem.width : scrollItem.height
+        property real scrollItemVisibleAreaPos: horizontal ? visibleArea.xPosition : visibleArea.yPosition
+        property real scrollItemVisibleAreaScrollRatio: horizontal ? visibleArea.widthRatio : visibleArea.heightRatio
+        property real scrollItemContentPos: horizontal ? scrollItem.contentX : scrollItem.contentY
+        property real scrollItemContentSize: horizontal ? scrollItem.contentWidth : scrollItem.contentHeight
+
+        property real offset: scrollItemVisibleAreaPos * scrollItemSize
+        property real length: scrollItemVisibleAreaScrollRatio * scrollItemSize
+        property real startOvershoot: Math.max(-scrollItemContentPos, 0)
+        property real endOvershoot: Math.max(scrollItemContentPos-(scrollItemContentSize-scrollItemSize), 0)
+        property real start: Math.max(offset + endOvershoot, 0)
+        property real end: Math.min(offset+length-startOvershoot, scrollItemSize)
+
+        Loader {
+            x: 0
+            y: parent.endOvershoot > 0 ? Math.min(parent.start, parent.scrollItemSize-width) : parent.start
+            width: 12
+            height: Math.max(parent.end-parent.start, width)
+
+            sourceComponent: content
+        }
+    }
+
+    DefaultStyles.ScrollIndicatorStyle { id: defaultStyle }
+}
diff --git a/components/custom/Slider.qml b/components/custom/Slider.qml
new file mode 100644
index 000000000..789167c66
--- /dev/null
+++ b/components/custom/Slider.qml
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Components project on Qt Labs.
+**
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions contained
+** in the Technology Preview License Agreement accompanying this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+****************************************************************************/
+
+import QtQuick 1.0
+import Qt.labs.components 1.0
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: slider
+
+    // COMMON API
+    property int orientation: Qt.Horizontal
+    property alias minimumValue: range.minimumValue
+    property alias maximumValue: range.maximumValue
+    property alias inverted: range.inverted
+    property bool updateValueWhileDragging: true
+    property alias pressed: mouseArea.pressed
+    property alias stepSize: range.stepSize
+
+    // NOTE: this property is in/out, the user can set it, create bindings to it, and
+    // at the same time the slider wants to update. There's no way in QML to do this kind
+    // of updates AND allow the user bind it (without a Binding object). That's the
+    // reason this is an alias to a C++ property in range model.
+    property alias value: range.value
+
+    // CONVENIENCE TO BE USED BY STYLES
+    SystemPalette {
+        id: palette
+    }
+    property color progressColor: palette.highlight
+    property color backgroundColor: palette.window
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int rightMargin: defaultStyle.rightMargin
+
+    // EXTENSIONS
+    // Indicate that we want animations in the Slider, people customizing should
+    // look at it to decide whether or not active animations.
+    property bool animated: true
+
+    // Value indicator displays the current value near the slider
+    property bool valueIndicatorVisible: true
+    property int valueIndicatorMargin: 10
+    property string valueIndicatorPosition: _isVertical ? "Left" : "Top"
+
+    // Reimplement this function to control how the value is shown in the
+    // indicator.
+    function formatValue(v) {
+        return Math.round(v);
+    }
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    // Hooks for customizing the pieces of the slider
+    property Component groove: defaultStyle.groove
+    property Component handle: defaultStyle.handle
+    property Component valueIndicator: defaultStyle.valueIndicator
+
+    // PRIVATE/CONVENIENCE
+    property bool _isVertical: orientation == Qt.Vertical
+
+    width: _isVertical ? minimumHeight : minimumWidth
+    height: _isVertical ? minimumWidth : minimumHeight
+
+    DefaultStyles.SliderStyle { id: defaultStyle }
+
+    // This is a template slider, so every piece can be modified by passing a
+    // different Component. The main elements in the implementation are
+    //
+    // - the 'range' does the calculations to map position to/from value,
+    //   it also serves as a data storage for both properties;
+    //
+    // - the 'fakeHandle' is what the mouse area drags on the screen, it feeds
+    //   the 'range' position and also reads it when convenient;
+    //
+    // - the real 'handle' it is the visual representation of the handle, that
+    //   just follows the 'fakeHandle' position.
+    //
+    // When the 'updateValueWhileDragging' is false and we are dragging, we stop
+    // feeding the range with position information, delaying until the next
+    // mouse release.
+    //
+    // Everything is encapsulated in a contents Item, so for the
+    // vertical slider, we just swap the height/width, make it
+    // horizontal, and then use rotation to make it vertical again.
+
+    Item {
+        id: contents
+
+        width: _isVertical ? slider.height : slider.width
+        height: _isVertical ? slider.width : slider.height
+        rotation: _isVertical ? -90 : 0
+
+        anchors.centerIn: slider
+
+        RangeModel {
+            id: range
+            minimumValue: 0
+            maximumValue: 100
+            value: 0
+            stepSize: 1.0
+            inverted: false
+
+            positionAtMinimum: leftMargin
+            positionAtMaximum: contents.width - rightMargin
+        }
+
+        Loader {
+            id: grooveLoader
+            anchors.fill: parent
+            sourceComponent: groove
+
+            property real handlePosition : handleLoader.x
+            function positionForValue(value) {
+                return range.positionForValue(value) - leftMargin;
+            }
+        }
+
+        Loader {
+            id: handleLoader
+            transform: Translate { x: - handleLoader.width / 2 }
+
+            anchors.verticalCenter: grooveLoader.verticalCenter
+
+            sourceComponent: handle
+
+            x: fakeHandle.x
+            Behavior on x {
+                id: behavior
+                enabled: !mouseArea.drag.active && slider.animated
+
+                PropertyAnimation {
+                    duration: behavior.enabled ? 150 : 0
+                    easing.type: Easing.OutSine
+                }
+            }
+        }
+
+        Item {
+            id: fakeHandle
+            width: handleLoader.width
+            height: handleLoader.height
+            transform: Translate { x: - handleLoader.width / 2 }
+        }
+
+        MouseArea {
+            id: mouseArea
+
+            anchors.centerIn: parent
+            anchors.horizontalCenterOffset: (slider.leftMargin - slider.rightMargin) / 2
+
+            width: parent.width + handleLoader.width - slider.rightMargin - slider.leftMargin
+            height: parent.height
+
+            drag.target: fakeHandle
+            drag.axis: Drag.XAxis
+            drag.minimumX: range.positionAtMinimum
+            drag.maximumX: range.positionAtMaximum
+
+            onPressed: {
+                // Clamp the value
+                var newX = Math.max(mouse.x, drag.minimumX);
+                newX = Math.min(newX, drag.maximumX);
+
+                // Debounce the press: a press event inside the handler will not
+                // change its position, the user needs to drag it.
+                if (Math.abs(newX - fakeHandle.x) > handleLoader.width / 2)
+                    range.position = newX;
+            }
+
+            onReleased: {
+                // If we don't update while dragging, this is the only
+                // moment that the range is updated.
+                if (!slider.updateValueWhileDragging)
+                    range.position = fakeHandle.x;
+            }
+        }
+
+        Loader {
+            id: valueIndicatorLoader
+
+            transform: Translate { x: - handleLoader.width / 2 }
+            rotation: _isVertical ? 90 : 0
+            visible: valueIndicatorVisible
+
+            // Properties available for the delegate component. Note that the indicatorText
+            // shows the value for the position the handle is, which is not necessarily the
+            // available as the current slider.value, since updateValueWhileDragging can
+            // be set to 'false'.
+            property string indicatorText: slider.formatValue(range.valueForPosition(handleLoader.x))
+            property bool dragging: mouseArea.drag.active
+
+            sourceComponent: valueIndicator
+
+            state: {
+                if (!_isVertical)
+                    return slider.valueIndicatorPosition;
+
+                if (valueIndicatorPosition == "Right")
+                    return "Bottom";
+                if (valueIndicatorPosition == "Top")
+                    return "Right";
+                if (valueIndicatorPosition == "Bottom")
+                    return "Left";
+
+                return "Top";
+            }
+
+            anchors.margins: valueIndicatorMargin
+
+            states: [
+                State {
+                    name: "Top"
+                    AnchorChanges {
+                        target: valueIndicatorLoader
+                        anchors.bottom: handleLoader.top
+                        anchors.horizontalCenter: handleLoader.horizontalCenter
+                    }
+                },
+                State {
+                    name: "Bottom"
+                    AnchorChanges {
+                        target: valueIndicatorLoader
+                        anchors.top: handleLoader.bottom
+                        anchors.horizontalCenter: handleLoader.horizontalCenter
+                    }
+                },
+                State {
+                    name: "Right"
+                    AnchorChanges {
+                        target: valueIndicatorLoader
+                        anchors.left: handleLoader.right
+                        anchors.verticalCenter: handleLoader.verticalCenter
+                    }
+                },
+                State {
+                    name: "Left"
+                    AnchorChanges {
+                        target: valueIndicatorLoader
+                        anchors.right: handleLoader.left
+                        anchors.verticalCenter: handleLoader.verticalCenter
+                    }
+                }
+            ]
+        }
+    }
+
+    // Range position normally follow fakeHandle, except when
+    // 'updateValueWhileDragging' is false. In this case it will only follow
+    // if the user is not pressing the handle.
+    Binding {
+        when: updateValueWhileDragging || !mouseArea.pressed
+        target: range
+        property: "position"
+        value: fakeHandle.x
+    }
+
+    // During the drag, we simply ignore position set from the range, this
+    // means that setting a value while dragging will not "interrupt" the
+    // dragging activity.
+    Binding {
+        when: !mouseArea.drag.active
+        target: fakeHandle
+        property: "x"
+        value: range.position
+    }
+}
diff --git a/components/custom/SpinBox.qml b/components/custom/SpinBox.qml
new file mode 100644
index 000000000..1566a8e72
--- /dev/null
+++ b/components/custom/SpinBox.qml
@@ -0,0 +1,142 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: spinbox
+    SystemPalette{id:syspal}
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int topMargin: defaultStyle.topMargin
+    property int rightMargin: defaultStyle.rightMargin
+    property int bottomMargin: defaultStyle.bottomMargin
+
+    width: Math.max(minimumWidth,
+                    input.width + leftMargin + rightMargin)
+
+    height: Math.max(minimumHeight,
+                     input.height + topMargin + bottomMargin)
+
+    property real value: 0.0
+    property real maximumValue: 99
+    property real minimumValue: 0
+    property real singlestep: 1
+
+    property bool upEnabled: value != maximumValue;
+    property bool downEnabled: value != minimumValue;
+
+    property alias upPressed: mouseUp.pressed
+    property alias downPressed: mouseDown.pressed
+    property alias upHovered: mouseUp.containsMouse
+    property alias downHovered: mouseDown.containsMouse
+    property alias containsMouse: mouseArea.containsMouse
+    property alias activeFocus: input.activeFocus // Forward active focus
+
+    property color backgroundColor: syspal.base
+    property color textColor: syspal.text
+
+    property Component background: defaultStyle.background
+    property Component up: defaultStyle.up
+    property Component down: defaultStyle.down
+    DefaultStyles.SpinBoxStyle { id: defaultStyle }
+
+    function increment() {
+        value += singlestep
+        if (value > maximumValue)
+            value = maximumValue
+        input.text = value
+    }
+
+    function decrement() {
+        value -= singlestep
+        if (value < minimumValue)
+            value = minimumValue
+        input.text = value
+    }
+
+    function setValue(v) {
+        var newval = parseFloat(v)
+        if (newval > maximumValue)
+            newval = maximumValue
+        else if (value < minimumValue)
+            newval = minimumValue
+        value = newval
+        input.text = value
+    }
+
+    // background
+    Loader {
+        id: backgroundComponent
+        anchors.fill: parent
+        sourceComponent: background
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+    }
+
+    TextInput {
+        id: input
+        font.pixelSize: 14
+        anchors.margins: 5
+        anchors.leftMargin: leftMargin
+        anchors.topMargin: topMargin
+        anchors.rightMargin: rightMargin
+        anchors.bottomMargin: bottomMargin
+        anchors.fill: parent
+        selectByMouse: true
+        text: spinbox.value
+        validator: DoubleValidator { bottom: 11; top: 31 }
+        onTextChanged: { spinbox.setValue(text); }
+        color: textColor
+        opacity: parent.enabled ? 1 : 0.5
+    }
+
+    Loader {
+        id: upButton
+        property alias pressed : spinbox.upPressed
+        property alias hover : spinbox.upHovered
+        property alias enabled : spinbox.upEnabled
+        sourceComponent: up
+        MouseArea {
+            id: mouseUp
+            anchors.fill: upButton.item
+            onClicked: increment()
+
+            property bool autoincrement: false;
+            onReleased: autoincrement = false
+            Timer { running: mouseUp.pressed; interval: 350 ; onTriggered: mouseUp.autoincrement = true }
+            Timer { running: mouseUp.autoincrement; interval: 60 ; repeat: true ; onTriggered: increment() }
+        }
+        onLoaded: {
+            item.parent = spinbox
+            mouseUp.parent = item
+        }
+    }
+
+    Loader {
+        id: downButton
+        property alias pressed : spinbox.downPressed
+        property alias hover : spinbox.downHovered
+        property alias enabled : spinbox.downEnabled
+        sourceComponent: down
+        MouseArea {
+            id: mouseDown
+            anchors.fill: downButton.item
+            onClicked: decrement()
+
+            property bool autoincrement: false;
+            onReleased: autoincrement = false
+            Timer { running: mouseDown.pressed; interval: 350 ; onTriggered: mouseDown.autoincrement = true }
+            Timer { running: mouseDown.autoincrement; interval: 60 ; repeat: true ; onTriggered: decrement() }
+        }
+        onLoaded: {
+            item.parent = spinbox
+            mouseDown.parent = item
+        }
+    }
+}
diff --git a/components/custom/Switch.qml b/components/custom/Switch.qml
new file mode 100644
index 000000000..8bf18cfe3
--- /dev/null
+++ b/components/custom/Switch.qml
@@ -0,0 +1,85 @@
+import QtQuick 1.1
+import "./styles/default" as DefaultStyles
+
+Item {
+    id: toggleSwitch    // "switch" is a reserved word
+
+    signal clicked
+    property bool pressed: mouseArea.pressed
+    property bool checked: false
+    property alias containsMouse: mouseArea.containsMouse
+
+    property color switchColor: syspal.button
+    property color backgroundColor: syspal.alternateBase
+    property color positiveHighlightColor: syspal.highlight
+    property color negativeHighlightColor: "transparent"
+    property color textColor: syspal.text
+
+    property Component groove: defaultStyle.groove
+    property Component handle: defaultStyle.handle
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    // implementation
+
+    implicitWidth: Math.max(minimumWidth, grooveLoader.item.implicitWidth)
+    implicitHeight: Math.max(minimumHeight, grooveLoader.item.implicitHeight)
+
+    onCheckedChanged: snapHandleIntoPlace();
+
+    Loader {
+        id: grooveLoader
+        anchors.fill: parent
+        property alias styledItem: toggleSwitch
+        property real handleCenterX: handleLoader.item.x + (handleLoader.item.width/2)
+        sourceComponent: groove
+    }
+
+    Loader {
+        id: handleLoader
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        property alias styledItem: toggleSwitch
+        sourceComponent: handle
+
+        Component.onCompleted: item.x = checked ? mouseArea.drag.maximumX : mouseArea.drag.minimumX
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+
+        drag.axis: Drag.XAxis
+        drag.minimumX: 0
+        drag.maximumX: toggleSwitch.width - handleLoader.item.width
+        drag.target: handleLoader.item
+
+        onPressed: toggleSwitch.pressed = true  // needed when hover is enabled
+        onCanceled: { snapHandleIntoPlace(); toggleSwitch.pressed = false; }   // mouse stolen e.g. by Flickable
+        onReleased: {
+            var wasChecked = checked;
+            if (drag.active) {
+                checked =  (handleLoader.item.x > (drag.maximumX - drag.minimumX)/2)
+            } else if (toggleSwitch.pressed && enabled) { // No click if release outside area
+                checked = !checked;
+            }
+
+            snapHandleIntoPlace();
+
+            toggleSwitch.pressed = false
+            if(checked != wasChecked)
+                toggleSwitch.clicked();
+        }
+    }
+
+    onWidthChanged: snapHandleIntoPlace()
+    function snapHandleIntoPlace() {
+        if(handleLoader.item)
+            handleLoader.item.x = checked ? mouseArea.drag.maximumX : mouseArea.drag.minimumX;
+    }
+
+    DefaultStyles.SwitchStyle { id: defaultStyle }
+    SystemPalette { id: syspal }
+}
diff --git a/components/custom/TextArea.qml b/components/custom/TextArea.qml
new file mode 100644
index 000000000..92263fe6e
--- /dev/null
+++ b/components/custom/TextArea.qml
@@ -0,0 +1,156 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+import "./behaviors"    // TextEditMouseBehavior
+
+FocusScope {
+    id: textArea
+
+    property alias text: textEdit.text
+    property alias placeholderText: placeholderTextComponent.text
+    property alias font: textEdit.font
+    property bool passwordMode: false
+    property bool readOnly: textEdit.readOnly // read only
+    property int inputHint; // values tbd   (alias to TextEdit.inputMethodHints?
+    property alias selectedText: textEdit.selectedText
+    property alias selectionEnd: textEdit.selectionEnd
+    property alias selectionStart: textEdit.selectionStart
+    property alias horizontalAlignment: textEdit.horizontalAlignment
+    property alias verticalAlignment: textEdit.verticalAlignment
+    property alias wrapMode: textEdit.wrapMode  //mm Missing from spec
+    property alias textFormat: textEdit.textFormat
+    property alias cursorPosition: textEdit.cursorPosition
+
+    property color textColor: syspal.text
+    property color backgroundColor: syspal.base
+    property alias containsMouse: mouseEditBehavior.containsMouse
+
+    property Component background: defaultStyle.background
+    property Component hints: defaultStyle.hints
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int topMargin: defaultStyle.topMargin
+    property int rightMargin: defaultStyle.rightMargin
+    property int bottomMargin: defaultStyle.bottomMargin
+
+    function copy() {
+        textEdit.copy()
+    }
+
+    function paste() {
+        textEdit.paste()
+    }
+
+    function cut() {
+        textEdit.cut()
+    }
+
+    function forceActiveFocus() {
+        textEdit.forceActiveFocus()
+    }
+
+    function select(start, end) {
+        textEdit.select(start, end)
+    }
+
+    function selectAll() {
+        textEdit.selectAll()
+    }
+
+    function selectWord() {
+        textEdit.selectWord()
+    }
+
+    function positionAt(x, y) {
+        var p = mapToItem(textEdit, x, y);
+        return textEdit.positionAt(p.x, p.y);
+    }
+
+    function positionToRectangle(pos) {
+        var p = mapToItem(textEdit, pos.x, pos.y);
+        return textEdit.positionToRectangle(p);
+    }
+
+    width: Math.max(minimumWidth,
+                    Math.max(textEdit.width, placeholderTextComponent.width) + leftMargin + rightMargin)
+    height: Math.max(minimumHeight,
+                     Math.max(textEdit.height, placeholderTextComponent.height) + topMargin + bottomMargin)
+
+
+    // Implementation
+
+    property alias activeFocus: textEdit.activeFocus // Forward active focus
+    property alias desktopBehavior: mouseEditBehavior.desktopBehavior
+    property alias _hints: hintsLoader.item
+    clip: true
+
+    SystemPalette { id: syspal }
+    Loader { id: hintsLoader; sourceComponent: hints }
+    Loader { sourceComponent: background; anchors.fill: parent }
+
+    Flickable { //mm is FocusScope, so TextArea's root doesn't need to be, no?
+        id: flickable
+        clip: true
+
+        anchors.fill: parent
+        anchors.leftMargin: leftMargin
+        anchors.topMargin: topMargin
+        anchors.rightMargin: rightMargin
+        anchors.bottomMargin: bottomMargin
+
+        function ensureVisible(r) {
+            if (contentX >= r.x)
+                contentX = r.x;
+            else if (contentX+width <= r.x+r.width)
+                contentX = r.x+r.width-width;
+            if (contentY >= r.y)
+                contentY = r.y;
+            else if (contentY+height <= r.y+r.height)
+                contentY = r.y+r.height-height;
+        }
+
+        TextEdit { // see QTBUG-14936
+            id: textEdit
+            font.pixelSize: _hints.fontPixelSize
+            font.bold: _hints.fontBold
+
+            anchors.top: parent.top
+            anchors.left: parent.left
+            anchors.right: parent.right
+
+            color: enabled ? textColor: Qt.tint(textColor, "#80ffffff")
+            wrapMode: desktopBehavior ? TextEdit.NoWrap : TextEdit.WordWrap
+            onCursorRectangleChanged: flickable.ensureVisible(cursorRectangle)
+
+            onActiveFocusChanged: activeFocus ? openSoftwareInputPanel() : closeSoftwareInputPanel()
+        }
+    }
+
+    Text {
+        id: placeholderTextComponent
+        x: leftMargin; y: topMargin
+        font: textEdit.font
+        opacity: !textEdit.text.length && !textEdit.activeFocus ? 1 : 0
+        color: "gray"
+        clip: true
+        text: "Enter text"
+        Behavior on opacity { NumberAnimation { duration: 90 } }
+    }
+
+
+    TextEditMouseBehavior {
+        id: mouseEditBehavior
+        anchors.fill: parent
+        textEdit: textEdit
+        desktopBehavior: false
+        copyPasteButtons: ButtonBlock {
+            opacity: 0  // initially hidden
+            Behavior on opacity { NumberAnimation { duration: 100 } }
+        }
+    }
+
+    DefaultStyles.TextFieldStyle { id: defaultStyle }
+}
+
diff --git a/components/custom/TextField.qml b/components/custom/TextField.qml
new file mode 100644
index 000000000..2af29427e
--- /dev/null
+++ b/components/custom/TextField.qml
@@ -0,0 +1,196 @@
+import QtQuick 1.0
+import "./styles/default" as DefaultStyles
+import "./behaviors"    // TextEditMouseBehavior
+
+// KNOWN ISSUES
+// 1) TextField does not loose focus when !enabled if it is a FocusScope (see QTBUG-16161)
+
+FocusScope {
+    id: textField
+
+    property alias text: textInput.text
+    property alias font: textInput.font
+
+    property int inputHint // values tbd
+    property bool acceptableInput: textInput.acceptableInput // read only
+    property bool readOnly: textInput.readOnly // read only
+    property alias placeholderText: placeholderTextComponent.text
+    property bool  passwordMode: false
+    property alias selectedText: textInput.selectedText
+    property alias selectionEnd: textInput.selectionEnd
+    property alias selectionStart: textInput.selectionStart
+    property alias validator: textInput.validator
+    property alias inputMask: textInput.inputMask
+    property alias horizontalalignment: textInput.horizontalAlignment
+    property alias echoMode: textInput.echoMode
+    property alias cursorPosition: textInput.cursorPosition
+    property alias inputMethodHints: textInput.inputMethodHints
+
+    property color textColor: syspal.text
+    property color backgroundColor: syspal.base
+    property alias containsMouse: mouseEditBehavior.containsMouse
+
+    property Component background: defaultStyle.background
+    property Component hints: defaultStyle.hints
+
+    property int minimumWidth: defaultStyle.minimumWidth
+    property int minimumHeight: defaultStyle.minimumHeight
+
+    property int leftMargin: defaultStyle.leftMargin
+    property int topMargin: defaultStyle.topMargin
+    property int rightMargin: defaultStyle.rightMargin
+    property int bottomMargin: defaultStyle.bottomMargin
+
+    function copy() {
+        textInput.copy()
+    }
+
+    function paste() {
+        textInput.paste()
+    }
+
+    function cut() {
+        textInput.cut()
+    }
+
+    function select(start, end) {
+        textInput.select(start, end)
+    }
+
+    function selectAll() {
+        textInput.selectAll()
+    }
+
+    function selectWord() {
+        textInput.selectWord()
+    }
+
+    function positionAt(x) {
+        var p = mapToItem(textInput, x, 0);
+        return textInput.positionAt(p.x);
+    }
+
+    function positionToRectangle(pos) {
+        var p = mapToItem(textInput, pos.x, pos.y);
+        return textInput.positionToRectangle(p);
+    }
+
+    width: Math.max(minimumWidth,
+                    textInput.width + leftMargin + rightMargin)
+
+    height: Math.max(minimumHeight,
+                     textInput.height + topMargin + bottomMargin)
+
+    // Forward focus property
+    property alias activeFocus: textInput.activeFocus
+
+    // Implementation
+
+    property alias desktopBehavior: mouseEditBehavior.desktopBehavior
+    property alias _hints: hintsLoader.item
+    clip: true
+
+    SystemPalette { id: syspal }
+    Loader { id: hintsLoader; sourceComponent: hints }
+    Loader { sourceComponent: background; anchors.fill:parent}
+
+    TextInput { // see QTBUG-14936
+        id: textInput
+        font.pixelSize: _hints.fontPixelSize
+        font.bold: _hints.fontBold
+
+        anchors.leftMargin: leftMargin
+        anchors.topMargin: topMargin
+        anchors.rightMargin: rightMargin
+        anchors.bottomMargin: bottomMargin
+
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.verticalCenter: parent.verticalCenter
+
+        opacity: desktopBehavior || activeFocus ? 1 : 0
+        color: enabled ? textColor : Qt.tint(textColor, "#80ffffff")
+        echoMode: passwordMode ? _hints.passwordEchoMode : TextInput.Normal
+
+        onActiveFocusChanged: {
+            if (!desktopBehavior)
+                state = (activeFocus ? "focused" : "")
+
+            if (activeFocus)
+                openSoftwareInputPanel()
+            else
+                closeSoftwareInputPanel()
+        }
+
+        states: [
+            State {
+                name: ""
+                PropertyChanges { target: textInput; cursorPosition: 0 }
+            },
+            State {
+                name: "focused"
+                PropertyChanges { target: textInput; cursorPosition: textInput.text.length }
+            }
+        ]
+
+        transitions: Transition {
+            to: "focused"
+            SequentialAnimation {
+                ScriptAction { script: textInput.cursorVisible = false; }
+                ScriptAction { script: textInput.cursorPosition = textInput.positionAt(textInput.width); }
+                NumberAnimation { target: textInput; property: "cursorPosition"; duration: 150 }
+                ScriptAction { script: textInput.cursorVisible = true; }
+            }
+        }
+    }
+
+    Text {
+        id: placeholderTextComponent
+        anchors.fill: textInput
+        font: textInput.font
+        opacity: !textInput.text.length && !textInput.activeFocus ? 1 : 0
+        color: "gray"
+        text: "Enter text"
+        Behavior on opacity { NumberAnimation { duration: 90 } }
+    }
+
+    Text {
+        id: unfocusedText
+        clip: true
+        anchors.fill: textInput
+        font: textInput.font
+        opacity: !desktopBehavior && !passwordMode && textInput.text.length && !textInput.activeFocus ? 1 : 0
+        color: textInput.color
+        elide: Text.ElideRight
+        text: textInput.text
+    }
+
+
+    TextEditMouseBehavior {
+        id: mouseEditBehavior
+        anchors.fill: parent
+        textInput: textInput
+        desktopBehavior: false
+        copyPasteButtons: ButtonBlock {
+            opacity: 0  // initially hidden
+            Behavior on opacity { NumberAnimation { duration: 100 } }
+        }
+    }
+
+    DefaultStyles.TextFieldStyle { id: defaultStyle }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/custom/behaviors/ButtonBehavior.qml b/components/custom/behaviors/ButtonBehavior.qml
new file mode 100644
index 000000000..391c870a7
--- /dev/null
+++ b/components/custom/behaviors/ButtonBehavior.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+
+Item {
+    id: behavior
+
+    signal clicked
+    property bool pressed: false    // Can't be alias of mouseArea.pressed because the latter is read-only
+    property alias containsMouse: mouseArea.containsMouse
+    property bool checkable: false
+    property bool checked: false
+    property bool triState: false
+
+    onCheckableChanged: { if(!checkable) checked = false }
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+        onPressed: behavior.pressed = true  // needed when hover is enabled
+        onEntered: if(pressed && enabled) behavior.pressed = true
+        onExited: behavior.pressed = false
+        onCanceled: behavior.pressed = false    // mouse stolen e.g. by Flickable
+        onReleased: {
+            if(behavior.pressed && behavior.enabled) { // No click if release outside area
+                behavior.pressed = false
+                if(behavior.checkable)
+                    behavior.checked = !behavior.checked;
+                behavior.clicked()
+            }
+        }
+    }
+}
diff --git a/components/custom/behaviors/ModalPopupBehavior.qml b/components/custom/behaviors/ModalPopupBehavior.qml
new file mode 100644
index 000000000..108bf02ae
--- /dev/null
+++ b/components/custom/behaviors/ModalPopupBehavior.qml
@@ -0,0 +1,90 @@
+import QtQuick 1.0
+
+// KNOWN ISSUES
+// none
+
+Item {
+    id: popupBehavior
+
+    property bool showing: false
+    property bool whenAlso: true            // modifier to the "showing" property
+    property bool consumeCancelClick: true
+    property int delay: 0                   // delay before popout becomes visible
+    property int deallocationDelay: 3000    // 3 seconds
+
+    property Component popupComponent
+
+    property alias popup: popupLoader.item  // read-only
+    property alias window: popupBehavior.root // read-only
+
+    signal prepareToShow
+    signal prepareToHide
+    signal cancelledByClick
+
+    // implementation
+
+    anchors.fill: parent
+
+    onShowingChanged: notifyChange()
+    onWhenAlsoChanged: notifyChange()
+    function notifyChange() {
+        if(showing && whenAlso) {
+            if(popupLoader.sourceComponent == undefined) {
+                popupLoader.sourceComponent = popupComponent;
+            }
+        } else {
+            mouseArea.enabled = false; // disable before opacity is changed in case it has fading behavior
+            if(Qt.isQtObject(popupLoader.item)) {
+                popupBehavior.prepareToHide();
+                popupLoader.item.opacity = 0;
+            }
+        }
+    }
+
+    property Item root: findRoot()
+    function findRoot() {
+        var p = parent;
+        while(p.parent != undefined)
+            p = p.parent;
+
+        return p;
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        enabled: false  // enabled only when popout is showing
+        onPressed: {
+            popupBehavior.showing = false;
+            mouse.accepted = consumeCancelClick;
+            cancelledByClick();
+        }
+    }
+
+    Loader {
+        id: popupLoader
+    }
+
+    Timer { // visibility timer
+        running: Qt.isQtObject(popupLoader.item) && showing && whenAlso
+        interval: delay
+        onTriggered: {
+            popupBehavior.prepareToShow();
+            mouseArea.enabled = true;
+            popup.opacity = 1;
+        }
+    }
+
+    Timer { // deallocation timer
+        running: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity == 0
+        interval: deallocationDelay
+        onTriggered: popupLoader.sourceComponent = undefined
+    }
+
+    states: State {
+        name: "active"
+        when: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity > 0
+        ParentChange { target: popupBehavior; parent: root }
+    }
+ }
+
diff --git a/components/custom/behaviors/TextEditMouseBehavior.qml b/components/custom/behaviors/TextEditMouseBehavior.qml
new file mode 100644
index 000000000..02175d5b9
--- /dev/null
+++ b/components/custom/behaviors/TextEditMouseBehavior.qml
@@ -0,0 +1,266 @@
+import QtQuick 1.0
+
+// KNOWN ISSUES
+// 1) Can't tell if the Paste button should be shown or not, see QTBUG-16190
+// 2) Hard to tell if the Select button should be shown (part of QTBUG-16190?)
+
+Item {
+    id: mouseBehavior
+
+    property TextInput textInput
+    property TextEdit textEdit
+    property Flickable flickable
+    property bool desktopBehavior: true
+    property alias containsMouse: mouseArea.containsMouse
+
+    property Component copyPasteButtons
+
+    // Implementation
+
+    property Item textEditor: Qt.isQtObject(textInput) ? textInput : textEdit
+
+    Connections {
+        target: textInput
+        onTextChanged: reset()
+        onCursorPositionChanged: reset()
+        onSelectedTextChanged: reset()
+        onActiveFocusChanged: reset()
+    }
+
+    function reset() {
+        copyPastePopup.showing = false; // hide and restart the visibility timer
+        copyPastePopup.showing = selectedText.length > 0 && !desktopBehavior;
+        copyPastePopup.wasCancelledByClick = false;
+        copyPastePopup.wasClosedByCopy = false;
+    }
+
+    Component.onCompleted: {
+        textEditor.focus = true;
+        textEditor.selectByMouse = false;
+        textEditor.activeFocusOnPress = false;
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+        drag.target: Item {} // work-around for Flickable stealing the mouse, which is expected (?), see QTBUG-15231
+
+        property int pressedPos
+        property int selectionStartAtPress
+        property int selectionEndAtPress
+        property bool hadFocusBeforePress
+        property bool draggingStartHandle
+        property bool draggingEndHandle
+
+        function characterPositionAt(mouse) {
+            var mappedMouse = mapToItem(textEditor, mouse.x, mouse.y);
+            if(Qt.isQtObject(textInput)) {
+                return textInput.positionAt(mappedMouse.x);
+            } else {
+                return textEdit.positionAt(mappedMouse.x, mappedMouse.y);
+            }
+        }
+
+        //mm see QTBUG-15814
+        onPressed: {
+            hadFocusBeforePress = textEditor.activeFocus;
+            selectionStartAtPress = textEditor.selectionStart;
+            selectionEndAtPress = textEditor.selectionEnd;
+
+            textEditor.forceActiveFocus();    //mm see QTBUG-16157
+            var pos = characterPositionAt(mouse);
+            if(desktopBehavior) {
+                textEditor.cursorPosition = pos;
+            } else {
+                draggingStartHandle = false;    // reset both to false, i.e. no dragging of selection endpoints
+                draggingEndHandle = false;
+                if(textEditor.selectionStart != textEditor.selectionEnd) {
+                    draggingEndHandle = (pos > selectionStartAtPress + (selectionEndAtPress-selectionStartAtPress)/2);
+                    draggingStartHandle = !draggingEndHandle;
+                }
+            }
+
+            pressedPos = textEditor.cursorPosition;
+        }
+
+        onPressAndHold: {
+            if(!desktopBehavior) {
+                if(!textEditor.selectedText.length) {   //mm Somehow just having the onPressAndHold impementation interrupts the text selection
+                    textEditor.cursorPosition = characterPositionAt(mouse);
+                }
+            }
+        }
+
+        onReleased: {
+            if(!desktopBehavior) {
+                if(mouse.wasHeld) copyPastePopup.showing = true;
+            }
+        }
+
+        onClicked: {
+            if(!desktopBehavior) {
+                if(!hadFocusBeforePress)
+                    return;
+
+                var pos = characterPositionAt(mouse);
+                if(textEditor.selectedText.length) { // clicked on or outside selection
+                    if(copyPastePopup.wasClosedByCopy && pos >= textEditor.selectionStart && pos < textEditor.selectionEnd)
+                        copyPastePopup.showing = true;
+                    else
+                        textEditor.select(textEditor.selectionEnd, textEditor.selectionEnd);   //mm use deselect() from QtQuick 1.1 (see QTBUG-16059)
+                } else {    // clicked while there's no selection
+                    if(pos == textEditor.cursorPosition) {  // Clicked where the cursor already where
+                        copyPastePopup.showing = !copyPastePopup.wasCancelledByClick;
+                        copyPastePopup.wasCancelledByClick = false;
+                    } else { // Clicked in a new place (where the cursor wasn't)
+                        var endOfWordRegEx = /[^\b]\b/g;
+                        endOfWordRegEx.lastIndex = pos;
+                        var endOfWordPosition = pos;
+                        if(endOfWordRegEx.test(textEditor.text))   // updates lastIndex
+                            endOfWordPosition = endOfWordRegEx.lastIndex;
+
+                        if(textEditor.cursorPosition != endOfWordPosition) {
+                            textEditor.cursorPosition = endOfWordPosition;
+                        } else {
+                            copyPastePopup.showing = !copyPastePopup.wasCancelledByClick;
+                            copyPastePopup.wasCancelledByClick = false;
+                        }
+                    }
+                }
+            }
+
+            textEditor.openSoftwareInputPanel()
+        }
+
+        onPositionChanged: {
+            if(!pressed)
+                return;
+
+            var pos = characterPositionAt(mouse);
+            if(desktopBehavior) {
+                textEditor.select(pressedPos, pos);
+            } else {
+                if(draggingStartHandle) {
+                    textEditor.select(selectionEndAtPress, pos);
+                } else if(draggingEndHandle) {
+                    textEditor.select(selectionStartAtPress, pos);
+                } else if(mouse.wasHeld && textEditor.cursorPosition != pos) {  // there's no selection
+                    textEditor.cursorPosition = pos;
+                    copyPastePopup.showing = true; // show once not pressed any more
+                }
+            }
+        }
+
+        onDoubleClicked: {
+            if(desktopBehavior)
+                textEditor.selectAll();
+            else {
+                textEditor.cursorPosition = characterPositionAt(mouse);
+                textEditor.selectWord(); // select word at cursor position
+            }
+        }
+    }
+
+
+    function selectionPopoutPoint() {
+        var point = {x:0, y:0}
+
+        var selectionStartRect = textEditor.positionToRectangle(textEditor.selectionStart);
+        var mappedStartPoint = mapFromItem(textEditor, selectionStartRect.x, selectionStartRect.y);
+        mappedStartPoint.x = Math.max(mappedStartPoint.x, 0);
+        mappedStartPoint.y = Math.max(mappedStartPoint.y, 0);
+
+        var selectioEndRect = textEditor.positionToRectangle(textEditor.selectionEnd);
+        var mappedEndPoint = mapFromItem(textEditor, selectioEndRect.x, selectioEndRect.y);
+        mappedEndPoint.x = Math.min(mappedEndPoint.x, textEditor.width);
+        mappedEndPoint.y = Math.min(mappedEndPoint.y, textEditor.height);
+
+        var multilineSelection = (selectionStartRect.y != selectioEndRect.y);
+        if(!multilineSelection) {
+            point.x = mappedStartPoint.x + (mappedEndPoint.x-mappedStartPoint.x)/2
+        } else {
+            point.x = textEditor.x + textEdit.width/2;
+        }
+
+        point.y = mappedStartPoint.y
+        return point;
+    }
+
+    Item {
+        id: copyPastePopup
+
+        property alias showing: modalPopup.showing
+        property bool wasCancelledByClick: false
+        property bool wasClosedByCopy: false
+
+        property bool showCopyAction: textEditor.selectedText.length > 0
+        property bool showCutAction: textEditor.selectedText.length > 0
+        property bool showPasteAction: true //textEditor.canPaste  //mm see QTBUG-16190
+        property bool showSelectAction: textEditor.text.length > 0 && textEditor.selectedText.length < textEditor.text.length // need canSelectWord, see QTBUG-16190
+        property bool showSelectAllAction: textEditor.text.length > 0 && textEditor.selectedText.length < textEditor.text.length
+
+        ListModel {
+            id: popupButtonModel
+            ListElement { text: "Copy"; opacity: 0 }        // index: 0
+            ListElement { text: "Cut"; opacity: 0 }         // index: 1
+            ListElement { text: "Paste"; opacity: 1 }       // index: 2
+            ListElement { text: "Select"; opacity: 0 }      // index: 3
+            ListElement { text: "Select all"; opacity: 0 }  // index: 4
+        }
+
+        onShowCopyActionChanged: popupButtonModel.setProperty(0, "opacity", showCopyAction ? 1 : 0);
+        onShowCutActionChanged: popupButtonModel.setProperty(1, "opacity", showCutAction ? 1 : 0);
+        onShowPasteActionChanged: popupButtonModel.setProperty(2, "opacity", showPasteAction ? 1 : 0);
+        onShowSelectActionChanged: popupButtonModel.setProperty(3, "opacity", showSelectAction ? 1 : 0);
+        onShowSelectAllActionChanged: popupButtonModel.setProperty(4, "opacity", showSelectAllAction ? 1 : 0);
+
+        Component.onCompleted: {
+            showCopyActionChanged();
+            showCutActionChanged();
+            showPasteActionChanged();
+            showSelectActionChanged();
+            showSelectAllActionChanged();
+        }
+
+        function positionPopout(popup, window) {   // position poput above the text field's cursor
+            var popoutPoint = selectionPopoutPoint();
+            var mappedPos = mapToItem(window, popoutPoint.x, popoutPoint.y);
+            popup.x = Math.max(mappedPos.x - popup.width/2, 0);
+            if(popup.x+popup.width > window.width)
+                popup.x = window.width-popup.width;
+
+            popup.y = mappedPos.y - popup.height;
+            if(popup.y < 0)
+                popup.y += popup.height + textEditor.height;
+        }
+
+        ModalPopupBehavior {
+            id: modalPopup
+            consumeCancelClick: false
+            whenAlso: !mouseArea.pressed
+            delay: 300
+            onPrepareToShow: copyPastePopup.positionPopout(popup, window)
+            onCancelledByClick: copyPastePopup.wasCancelledByClick = true
+
+            popupComponent: copyPasteButtons
+            onPopupChanged: if(popup) popup.model = popupButtonModel
+
+            Connections {
+                target: modalPopup.popup
+                onClicked: {
+                    if(index == 0) {
+                        textEditor.copy();
+                        copyPastePopup.showing = false;
+                        copyPastePopup.wasClosedByCopy = true;
+                    }
+                    if(index == 1) textEditor.cut();
+                    if(index == 2) textEditor.paste();
+                    if(index == 3) textEditor.selectWord();
+                    if(index == 4) textEditor.selectAll();
+                }
+            }
+        }
+    }
+}
+
diff --git a/components/custom/components.pro b/components/custom/components.pro
new file mode 100644
index 000000000..be0663d70
--- /dev/null
+++ b/components/custom/components.pro
@@ -0,0 +1,49 @@
+TEMPLATE = subdirs # XXX: Avoid call the linker
+TARGETPATH = Qt/labs/components/custom
+
+symbian {
+    INSTALL_IMPORTS = /resource/qt/imports
+} else {
+    INSTALL_IMPORTS = $$[QT_INSTALL_IMPORTS]
+}
+
+QML_FILES = \
+        qmldir \
+        BasicButton.qml \
+        BusyIndicator.qml \
+        ButtonBlock.qml \
+        ButtonColumn.qml \
+        ButtonRow.qml \
+        ButtonGroup.js \
+        Button.qml \
+        CheckBox.qml \
+        ChoiceList.qml \
+        ProgressBar.qml \
+        RadioButton.qml \
+        ScrollDecorator.qml \
+        ScrollIndicator.qml \
+        Slider.qml \
+        SpinBox.qml \
+        Switch.qml \
+        TextArea.qml \
+        TextField.qml
+
+QML_DIRS = \
+        behaviors \
+        private \
+        styles \
+        visuals
+
+qmlfiles.files = $$QML_FILES
+qmlfiles.sources = $$QML_FILES
+qmlfiles.path = $$INSTALL_IMPORTS/$$TARGETPATH
+
+qmldirs.files = $$QML_DIRS
+qmldirs.sources = $$QML_DIRS
+qmldirs.path = $$INSTALL_IMPORTS/$$TARGETPATH
+
+INSTALLS += qmlfiles qmldirs
+
+symbian {
+    DEPLOYMENT += qmlfiles qmldirs
+}
diff --git a/components/custom/private/ChoiceListPopup.qml b/components/custom/private/ChoiceListPopup.qml
new file mode 100644
index 000000000..61a0d2220
--- /dev/null
+++ b/components/custom/private/ChoiceListPopup.qml
@@ -0,0 +1,269 @@
+import QtQuick 1.0
+
+MouseArea {
+    id: popup
+    // There is no global toplevel so we have to make one
+    // We essentially reparent this item to the root item
+    Component.onCompleted: {
+        var p = parent;
+        while (p.parent != undefined)
+            p = p.parent
+        parent = p;
+    }
+
+    anchors.fill: parent  // fill the while app area
+    opacity: popupFrameLoader.item.opacity  // let the frame control opacity, so it can set the behavior
+
+    property string behavior: "MacOS"
+    property bool desktopBehavior: (behavior == "MacOS" || behavior == "Windows" || behavior == "Linux")
+    property int previousCurrentIndex: -1   // set in state transition last in this file
+
+    property alias model: listView.model
+    property alias currentIndex: listView.currentIndex
+
+    property Component listItem
+    property Component listHighlight
+    property Component popupFrame
+
+    function togglePopup() { state = (state == "" ? "hidden" : "") }
+    function setCurrentIndex(index) { listView.currentIndex = index; }
+    function cancelSelection() { listView.currentIndex = previousCurrentIndex; }
+    function closePopup() { state = "hidden" }
+
+    function positionPopup() {
+        switch(behavior) {
+        case "MacOS":
+            var mappedListPos = mapFromItem(choiceList, 0, 0);
+            var itemHeight = Math.max(listView.contentHeight/listView.count, 0);
+            var currentItemY = Math.max(currentIndex*itemHeight, 0);
+            currentItemY += Math.floor(itemHeight/2 - choiceList.height/2);  // correct for choiceLists that are higher than items in the list
+
+            listView.y = mappedListPos.y - currentItemY;
+            listView.x = mappedListPos.x;
+
+            listView.width = choiceList.width;
+            listView.height = listView.contentHeight    //mm see QTBUG-16037
+
+            if(listView.y < topMargin) {
+                var excess = Math.floor(currentItemY - mappedListPos.y);
+                listView.y = topMargin;
+                listView.height += excess;
+                listView.contentY = excess + topMargin;
+
+                if(listView.contentY != excess+topMargin) //mm setting listView.height seems to make it worse
+                    print("!!! ChoiceListPopup.qml: listView.contentY should be " + excess+topMargin + " but is " + listView.contentY)
+            }
+
+            if(listView.height+listView.contentY > listView.contentHeight) {
+                listView.height = listView.contentHeight-listView.contentY;
+            }
+
+            if(listView.y+listView.height+bottomMargin > popup.height) {
+                listView.height = popup.height-listView.y-bottomMargin;
+            }
+            break;
+        case "Windows":
+            var point = popup.mapFromItem(choiceList, 0, listView.height);
+            listView.y = point.y;
+            listView.x = point.x;
+
+            listView.width = choiceList.width;
+            listView.height = 200;
+
+            break;
+        case "MeeGo":
+            break;
+        }
+    }
+
+    Loader {
+        id: popupFrameLoader
+        property alias styledItem: popup.parent
+        anchors.fill: listView
+        anchors.leftMargin: -item.anchors.leftMargin
+        anchors.rightMargin: -item.anchors.rightMargin
+        anchors.topMargin: -item.anchors.topMargin
+        anchors.bottomMargin: -item.anchors.bottomMargin
+        sourceComponent: popupFrame
+    }
+
+    ListView {
+        id: listView
+        focus: true
+        boundsBehavior: desktopBehavior ? ListView.StopAtBounds : ListView.DragOverBounds
+        keyNavigationWraps: !desktopBehavior
+        highlightFollowsCurrentItem: false  // explicitly handled below
+
+        interactive: !desktopBehavior   // disable flicking. also disables key handling
+        onCurrentItemChanged: {
+            if(desktopBehavior) {
+                positionViewAtIndex(currentIndex, ListView.Contain);
+            }
+        }
+
+        property int highlightedIndex: -1
+        onHighlightedIndexChanged: positionViewAtIndex(highlightedIndex, ListView.Contain)
+
+        property variant highlightedItem: null
+        onHighlightedItemChanged: {
+            if(desktopBehavior) {
+                positionHighlight();
+            }
+        }
+
+        function positionHighlight() {
+            if(!Qt.isQtObject(highlightItem))
+                return;
+
+            if(!Qt.isQtObject(highlightedItem)) {
+                highlightItem.opacity = 0;  // hide when no item is highlighted
+            } else {
+                highlightItem.x = highlightedItem.x;
+                highlightItem.y = highlightedItem.y;
+                highlightItem.width = highlightedItem.width;
+                highlightItem.height = highlightedItem.height;
+                highlightItem.opacity = 1;  // show once positioned
+            }
+        }
+
+        function hideHighlight() {
+            highlightedIndex = -1;
+            highlightedItem = null; // will trigger positionHighlight() what will hide the highlight
+        }
+
+        delegate: Item {
+            id: itemDelegate
+            width: delegateLoader.item.width
+            height: delegateLoader.item.height
+            property int theIndex: index    // for some reason the loader can't bind directly to the "index"
+
+            Loader {
+                id: delegateLoader
+                property variant model: listView.model
+                property alias index: itemDelegate.theIndex //mm Somehow the "model" gets through automagically, but not index
+                property Item styledItem: choiceList
+                property bool highlighted: theIndex == listView.highlightedIndex
+                sourceComponent: listItem
+                MouseArea { // handle list selection on mobile platforms
+                    id:itemMouseArea
+                    anchors.fill: parent
+                    onClicked: { setCurrentIndex(index); closePopup(); }
+                }
+            }
+
+            states: State {
+                name: "highlighted"
+                when: index == listView.highlightedIndex
+                StateChangeScript {
+                    script: {
+                        if(Qt.isQtObject(listView.highlightedItem)) {
+                            listView.highlightedItem.yChanged.disconnect(listView.positionHighlight);
+                        }
+                        listView.highlightedItem = itemDelegate;
+                        listView.highlightedItem.yChanged.connect(listView.positionHighlight);
+                    }
+                }
+
+            }
+        }
+
+        function firstVisibleItem() { return indexAt(contentX+10,contentY+10); }
+        function lastVisibleItem() { return indexAt(contentX+width-10,contentY+height-10); }
+        function itemsPerPage() { return lastVisibleItem() - firstVisibleItem(); }
+
+        Keys.onPressed: {
+            // with the ListView !interactive (non-flicking) we have to handle arrow keys
+            if (event.key == Qt.Key_Up) {
+                if(!highlightedItem) highlightedIndex = lastVisibleItem();
+                else if(highlightedIndex > 0) highlightedIndex--;
+            } else if (event.key == Qt.Key_Down) {
+                if(!highlightedItem) highlightedIndex = firstVisibleItem();
+                else if(highlightedIndex+1 < model.count) highlightedIndex++;
+            } else if (event.key == Qt.Key_PageUp) {
+                if(!highlightedItem) highlightedIndex = lastVisibleItem();
+                else highlightedIndex = Math.max(highlightedIndex-itemsPerPage(), 0);
+            } else if (event.key == Qt.Key_PageDown) {
+                if(!highlightedItem) highlightedIndex = firstVisibleItem();
+                else highlightedIndex = Math.min(highlightedIndex+itemsPerPage(), model.count-1);
+            } else if (event.key == Qt.Key_Home) {
+                highlightedIndex = 0;
+            } else if (event.key == Qt.Key_End) {
+                highlightedIndex = model.count-1;
+            } else if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
+                if(highlightedIndex != -1) {
+                    popup.setCurrentIndex(highlightedIndex);
+                } else {
+                    popup.cancelSelection();
+                }
+
+                popup.closePopup();
+            } else if (event.key == Qt.Key_Escape) {
+                popup.cancelSelection();
+                popup.closePopup();
+            }
+            event.accepted = true;  // consume all keys while popout has focus
+        }
+
+        highlight: popup.listHighlight
+    }
+
+    enabled: (state != "hidden") // to avoid stray events when poput is about to close
+    hoverEnabled: true
+    onClicked: { popup.cancelSelection(); popup.closePopup(); } // clicked outside the list
+    onPressed: {
+        var mappedPos = mapToItem(listView.contentItem, mouse.x, mouse.y);
+        var indexAt = listView.indexAt(mappedPos.x, mappedPos.y);
+        if(indexAt != -1) {
+            listView.currentIndex = indexAt;
+        }
+    }
+    onPositionChanged: {
+        var mappedPos = mapToItem(listView.contentItem, mouse.x, mouse.y);
+        var indexAt = listView.indexAt(mappedPos.x, mappedPos.y);
+        if(!pressed) {   // hovering
+            if(indexAt == listView.highlightedIndex)
+                return;
+
+            if(indexAt >= 0) {
+                listView.highlightedIndex = indexAt;
+            } else {
+                if(mouse.y > listView.y+listView.height && listView.highlightedIndex+1 < listView.count ) {
+                    listView.highlightedIndex++;
+                } else if(mouse.y < listView.y && listView.highlightedIndex > 0) {
+                    listView.highlightedIndex--;
+                } else if(mouse.x < popupFrameLoader.x || mouse.x > popupFrameLoader.x+popupFrameLoader.width) {
+                    listView.hideHighlight();
+                }
+            }
+        }
+    }
+
+    state: "hidden" // hidden by default
+    states: [
+        State {
+            name: ""    // not hidden, i.e. showing
+            PropertyChanges { target: popupFrameLoader.item; opacity: 1 }
+        },
+        State {
+            name: "hidden"
+            PropertyChanges { target: popupFrameLoader.item; opacity: 0 }
+        }
+    ]
+
+    transitions: [
+        Transition { to: "";
+            ScriptAction {
+                script: {
+                    previousCurrentIndex = currentIndex;
+                    positionPopup();
+                    listView.forceActiveFocus();
+                }
+            }
+        },
+        Transition { to: "hidden"; ScriptAction { script: listView.hideHighlight(); } }
+    ]
+}
+
+
+
+
diff --git a/components/custom/qmldir b/components/custom/qmldir
new file mode 100644
index 000000000..6e256a81d
--- /dev/null
+++ b/components/custom/qmldir
@@ -0,0 +1,17 @@
+BasicButton 1.0 BasicButton.qml
+BusyIndicator 1.0 BusyIndicator.qml
+ButtonBlock 1.0 ButtonBlock.qml
+Button 1.0 Button.qml
+ButtonColumn 1.0 ButtonColumn.qml
+ButtonRow 1.0 ButtonRow.qml
+CheckBox 1.0 CheckBox.qml
+ChoiceList 1.0 ChoiceList.qml
+ProgressBar 1.0 ProgressBar.qml
+RadioButton 1.0 RadioButton.qml
+ScrollDecorator 1.0 ScrollDecorator.qml
+ScrollIndicator 1.0 ScrollIndicator.qml
+Slider 1.0 Slider.qml
+SpinBox 1.0 SpinBox.qml
+Switch 1.0 Switch.qml
+TextArea 1.0 TextArea.qml
+TextField 1.0 TextField.qml
diff --git a/components/custom/styles/default/BasicButtonStyle.qml b/components/custom/styles/default/BasicButtonStyle.qml
new file mode 100644
index 000000000..08b18040e
--- /dev/null
+++ b/components/custom/styles/default/BasicButtonStyle.qml
@@ -0,0 +1,8 @@
+import QtQuick 1.1
+
+QtObject {
+    property int minimumWidth: 40
+    property int minimumHeight: 25
+
+    property Component background: Component { Item { } }
+}
diff --git a/components/custom/styles/default/BusyIndicatorStyle.qml b/components/custom/styles/default/BusyIndicatorStyle.qml
new file mode 100644
index 000000000..83ef46fd7
--- /dev/null
+++ b/components/custom/styles/default/BusyIndicatorStyle.qml
@@ -0,0 +1,21 @@
+import QtQuick 1.0
+
+QtObject {
+    property Component background:
+    Component {
+        Image {
+            opacity: running ? 1.0 : 0.7    //mm Should the rotation fade and stop when indicator is !enabled?
+            source: "images/spinner.png";
+            fillMode: Image.PreserveAspectFit
+            smooth: true
+
+            property int steps: 12
+            property int rotationStep: 0
+            rotation: rotationStep*(360/steps)
+            NumberAnimation on rotationStep {
+                running: busyIndicator.running; from: 0; to: steps; //mm see QTBUG-15652
+                loops: Animation.Infinite; duration: 1000 // 1s per revolution
+            }
+        }
+    }
+}
diff --git a/components/custom/styles/default/ButtonBlockStyle.qml b/components/custom/styles/default/ButtonBlockStyle.qml
new file mode 100644
index 000000000..f0bed8654
--- /dev/null
+++ b/components/custom/styles/default/ButtonBlockStyle.qml
@@ -0,0 +1,77 @@
+import QtQuick 1.0
+
+QtObject {
+    property int minimumWidth: 90
+    property int minimumHeight: 32
+
+    property int leftMargin : 8
+    property int topMargin: 8
+    property int rightMargin: 8
+    property int bottomMargin: 8
+
+    property Component background:
+    Component {
+        id: defaultBackground
+        Item {
+            opacity: enabled ? 1 : 0.7
+            Rectangle { // Background center fill
+                anchors.fill: parent
+                anchors.leftMargin: adjoining&Qt.Horizontal ? 0 : 2
+                anchors.rightMargin: anchors.leftMargin
+                anchors.topMargin: adjoining&Qt.Vertical ? 0 : 2
+                anchors.bottomMargin: anchors.topMargin
+
+                radius: adjoining ? 0 : 5
+                color: !styledItem.checked ? backgroundColor : Qt.darker(backgroundColor)
+            }
+            BorderImage {
+                anchors.fill: parent
+                smooth: true
+                source: {
+                    if(!adjoining)
+                        return styledItem.pressed || styledItem.checked ? "images/button_pressed.png" : "images/button_normal.png";
+                    else if(adjoining&Qt.Horizontal)
+                        return styledItem.pressed || styledItem.checked ? "images/buttongroup_h_pressed.png" : "images/buttongroup_h_normal.png";
+                    else // adjoining&Qt.Vertical
+                        return styledItem.pressed || styledItem.checked ? "images/buttongroup_v_pressed.png" : "images/buttongroup_v_normal.png";
+                }
+                border.left: 6; border.top: 6
+                border.right: 6; border.bottom: 6
+            }
+        }
+    }
+
+    property Component label:
+    Component {
+        id: defaultLabel
+        Item {
+            width: row.width
+            height: row.height
+            anchors.centerIn: parent    //mm see QTBUG-15619
+            opacity: styledItem.enabled ? 1 : 0.5
+            transform: Translate {
+                x: styledItem.pressed || styledItem.checked ? 1 : 0
+                y: styledItem.pressed || styledItem.checked ? 1 : 0
+            }
+
+            Row {
+                id: row
+                anchors.centerIn: parent
+                spacing: 4
+                Image {
+                    source: styledItem.iconSource
+                    anchors.verticalCenter: parent.verticalCenter
+                    fillMode: Image.Stretch //mm Image should shrink if button is too small, depends on QTBUG-14957
+                }
+
+                Text {
+                    color: styledItem.textColor
+                    anchors.verticalCenter: parent.verticalCenter
+                    text: styledItem.text
+                    horizontalAlignment: Text.Center
+                    elide: Text.ElideRight //mm can't make layout work as desired without implicit size support, see QTBUG-14957
+                }
+            }
+        }
+    }
+}
diff --git a/components/custom/styles/default/ButtonStyle.qml b/components/custom/styles/default/ButtonStyle.qml
new file mode 100644
index 000000000..a0e5f3302
--- /dev/null
+++ b/components/custom/styles/default/ButtonStyle.qml
@@ -0,0 +1,102 @@
+import QtQuick 1.1
+
+QtObject {
+    property int minimumWidth: 90
+    property int minimumHeight: 32
+
+    property int leftMargin: 8
+    property int topMargin: 8
+    property int rightMargin: 8
+    property int bottomMargin: 8
+
+    property Component background: Component {
+        Item {
+            opacity: enabled ? 1 : 0.7
+            clip: true  // clip connected buttons, as they overlap to remove the rounded edjes
+            property bool isPositioned: position != "only" // only evaluate for rows and columns
+
+            Item {
+                anchors.fill: parent
+                // Give connected buttons a negative styling margin, to make
+                // them overlap and the rounded edge can be clipped away
+                anchors.leftMargin:   isPositioned && (position == "rightmost"  || position =="h_middle") ? -leftMargin : 0
+                anchors.rightMargin:  isPositioned && (position == "leftmost"   || position =="h_middle") ? -rightMargin : 0
+                anchors.topMargin:    isPositioned && (position == "bottom"     || position =="v_middle") ? -bottomMargin : 0
+                anchors.bottomMargin: isPositioned && (position == "top"        || position =="v_middle") ? -topMargin : 0
+
+                Rectangle { // Background center fill
+                    anchors.fill: parent
+                    anchors.leftMargin: anchors.leftMargin
+                    anchors.rightMargin: anchors.rightMargin
+                    anchors.topMargin: anchors.topMargin
+                    anchors.bottomMargin: anchors.bottomMargin
+                    radius: 5
+                    color: backgroundColor
+                }
+                BorderImage {
+                    anchors.fill: parent
+                    smooth: true
+                    source: pressed || checked ? "images/button_pressed.png" : "images/button_normal.png";
+                    border.left: 6; border.top: 6
+                    border.right: 6; border.bottom: 6
+                }
+            }
+
+            // Draw straight border lines between connected buttons
+            Rectangle {
+                width: 1
+                visible: isPositioned && !checked && !pressed && (position == "rightmost" || position == "h_middle")
+                anchors.top: parent.top
+                anchors.topMargin: 2
+                anchors.bottomMargin: 2
+                anchors.bottom: parent.bottom
+                anchors.left: parent.left
+                opacity: 0.4
+                color: "white"
+            }
+            Rectangle {
+                width: 1
+                opacity: 0.4
+                visible: isPositioned && !checked && !pressed && (position == "leftmost" || position == "h_middle")
+                anchors.top: parent.top
+                anchors.topMargin: 2
+                anchors.bottomMargin: 2
+                anchors.bottom: parent.bottom
+                anchors.right: parent.right
+                color: "black"
+            }
+        }
+    }
+
+    property Component label: Component {
+        Item {
+            implicitWidth: row.implicitWidth
+            implicitHeight: row.implicitHeight
+
+            opacity: enabled ? 1 : 0.5
+            transform: Translate {
+                x: pressed || checked ? 1 : 0
+                y: pressed || checked ? 1 : 0
+            }
+
+            Row {
+                id: row
+                anchors.centerIn: parent
+                spacing: 4
+                Image {
+                    source: iconSource
+                    anchors.verticalCenter: parent.verticalCenter
+                    fillMode: Image.Stretch //mm Image should shrink if button is too small, depends on QTBUG-14957
+                }
+
+                Text {
+                    color: textColor
+                    anchors.verticalCenter: parent.verticalCenter
+                    text: styledItem.text
+                    horizontalAlignment: Text.Center
+                    elide: Text.ElideRight //mm can't make layout work as desired without implicit size support, see QTBUG-14957
+                }
+            }
+        }
+    }
+}
diff --git a/components/custom/styles/default/CheckBoxStyle.qml b/components/custom/styles/default/CheckBoxStyle.qml
new file mode 100644
index 000000000..f5e5fdded
--- /dev/null
+++ b/components/custom/styles/default/CheckBoxStyle.qml
@@ -0,0 +1,34 @@
+import QtQuick 1.1
+
+QtObject {
+    property int minimumWidth: 32
+    property int minimumHeight: 32
+
+    property Component background: Component {
+        Item {
+            width: styledItem.implicitWidth; height: styledItem.implicitHeight
+            opacity: enabled ? 1 : 0.7
+            Rectangle { // Background center fill
+                anchors.fill: parent
+                anchors.margins: 1
+                radius: 5
+                color: backgroundColor
+            }
+            BorderImage {
+                anchors.fill: parent
+                source: "images/lineedit_normal.png"
+                smooth: true
+                border.left: 6; border.top: 3
+                border.right: 6; border.bottom: 3
+            }
+        }
+    }
+
+    property Component checkmark: Component {
+        Image {
+            source: "images/checkbox_check.png"
+            opacity: (!enabled && checked) || pressed == true ? 0.5 : (!checked ? 0 : 1)
+            Behavior on opacity { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }
+        }
+    }
+}
diff --git a/components/custom/styles/default/ChoiceListStyle.qml b/components/custom/styles/default/ChoiceListStyle.qml
new file mode 100644
index 000000000..12b10ffd5
--- /dev/null
+++ b/components/custom/styles/default/ChoiceListStyle.qml
@@ -0,0 +1,100 @@
+import QtQuick 1.0
+
+QtObject {
+    property int minimumWidth: 200
+    property int minimumHeight: 32
+
+    property int leftMargin: 8
+    property int topMargin: 8
+    property int rightMargin: 34
+    property int bottomMargin: 8
+
+    property Component background: Component {
+        Item {
+            opacity: enabled ? 1 : 0.8
+            Rectangle { // Background center fill
+                anchors.fill: parent
+                anchors.margins: 1
+                color: backgroundColor
+                radius: 5
+            }
+            BorderImage {
+                anchors.fill: parent
+                id: backgroundimage
+                smooth: true
+                source: styledItem.pressed ? "images/button_pressed.png" : "images/button_normal.png"
+                width: 80; height: 24
+                border.left: 3; border.top: 3
+                border.right: 3; border.bottom: 3
+                Image {
+                    anchors.verticalCenter: parent.verticalCenter
+                    anchors.right: parent.right
+                    anchors.rightMargin: 10
+                    opacity: enabled ? 1 : 0.3
+                    source:"images/spinbox_down.png"
+                }
+            }
+        }
+    }
+
+    property Component label: Component {
+        Text {
+            id:t
+            color: textColor
+            text: model && currentIndex >= 0 ? model.get(currentIndex).text : ""
+            opacity: enabled ? 1 : 0.5
+        }
+    }
+
+    // Popout styling
+
+    property Component popupFrame: Component {
+        Item {
+            Behavior on opacity { NumberAnimation { easing.type: Easing.OutQuad; duration: 250 } }
+
+            anchors.leftMargin: 6
+            anchors.topMargin: 6
+            anchors.rightMargin: 7
+            anchors.bottomMargin: 6
+
+            Rectangle { // Background center fill
+                anchors.fill: parent
+                anchors.margins: 1
+                color: backgroundColor
+                radius: 5
+            }
+            BorderImage {
+                anchors.fill: parent
+                id: backgroundimage
+                smooth: true
+                source: "images/button_normal.png"
+                width: 80; height: 24
+                border.left: 5; border.top: 5
+                border.right: 5; border.bottom: 5
+            }
+        }
+    }
+
+    property Component listItem: Component {
+        Rectangle {
+            width: styledItem.width
+            height: Math.max(itemText.height, 28)
+            color: highlighted ? "#556699" : "transparent"
+	    radius:2
+	    border.width:1
+	    border.color:Qt.darker(color)
+	    clip:true
+            Text {
+                id: itemText
+                anchors.verticalCenter: parent.verticalCenter
+                anchors.left: parent.left
+                anchors.leftMargin: 6
+
+                font.bold: index == currentIndex
+                color: highlighted ? "white" : styledItem.textColor
+                anchors.margins: 10
+                text: model ? model.get(index).text : ""  // list properties can't be automatically be added to the scope, so use get()
+            }
+        }
+    }
+}
diff --git a/components/custom/styles/default/ProgressBarStyle.qml b/components/custom/styles/default/ProgressBarStyle.qml
new file mode 100644
index 000000000..7cb9795c1
--- /dev/null
+++ b/components/custom/styles/default/ProgressBarStyle.qml
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Components project on Qt Labs.
+**
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions contained
+** in the Technology Preview License Agreement accompanying this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+QtObject {
+    property int minimumWidth: 200
+    property int minimumHeight: 25
+
+    property int leftMargin: 0
+    property int rightMargin: 0
+    property int topMargin: 0
+    property int bottomMargin: 0
+
+    property Component background: Component {
+        Item{
+            Rectangle{
+                anchors.fill:parent
+                width: parent.width-2
+                height: parent.height-2
+                color: backgroundColor
+                radius: 5
+            }
+            BorderImage {
+                anchors.fill:parent
+                source:"images/progressbar_groove.png"
+                border.left:10; border.right:10
+                border.top:10; border.bottom:10
+            }
+        }
+    }
+
+    property Component progress: Component {    // progress bar, known duration
+        BorderImage { // green progress indication
+            id:progress
+            opacity: styledItem.enabled ? 1: 0.7
+            source: complete > 0.95 ?
+                    "images/progressbar_indeterminate.png" : "images/progressbar_fill.png"
+            border.left:complete > 0.1 ? 6: 2;
+            border.right:complete > 0.1 ? 6: 2
+            border.top:10; border.bottom:10
+            clip:true
+
+            Rectangle{
+                anchors.fill:progress
+                color: styledItem.progressColor
+                z:-1
+                radius:2
+                smooth:true
+                clip:true
+                anchors.rightMargin:0
+                anchors.margins:1
+                Image {
+                    id: overlay
+                    NumberAnimation on x {
+                        loops:Animation.Infinite;
+                        from:0;
+                        to:-overlay.sourceSize.width;
+                        duration:2000
+                    }
+                    width:styledItem.width + sourceSize.width
+                    height:styledItem.height
+                    fillMode:Image.Tile
+                    source: "images/progressbar_overlay.png"
+                }
+            }
+        }
+    }
+
+    property Component indeterminateProgress: Component {   // progress bar, unknown duration
+        Item {
+            id: bar
+            anchors.fill:parent
+            onWidthChanged:indicator.x = width-indicator.width
+            BorderImage {
+                id:indicator
+                opacity: styledItem.enabled ? 1: 0.7
+                Behavior on x {
+                    NumberAnimation{easing.type:Easing.Linear; duration:1000}
+                }
+                onXChanged: {
+                    var w = bar.width - indicator.width
+                    if (x == w) x = 0
+                    else if (x==0) x = w
+                }
+                width: 80
+                height: parent.height
+                source:"images/progressbar_indeterminate.png"
+                border.left:10 ; border.right:10
+                border.top:10 ; border.bottom:10
+                clip:true
+
+                Rectangle{
+                    anchors.fill:indicator
+                    color: styledItem.progressColor
+                    z:-1
+                    radius:2
+                    smooth:true
+                    clip:true
+                    anchors.rightMargin:0
+                    anchors.margins:1
+                    Image {
+                        id: overlay
+                        NumberAnimation on x {
+                            loops:Animation.Infinite;
+                            from:0;
+                            to:-overlay.sourceSize.width;
+                            duration:2000
+                        }
+                        width:styledItem.width + sourceSize.width
+                        height:styledItem.height
+                        fillMode:Image.Tile
+                        source: "images/progressbar_overlay.png"
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/components/custom/styles/default/RadioButtonStyle.qml b/components/custom/styles/default/RadioButtonStyle.qml
new file mode 100644
index 000000000..0381993e4
--- /dev/null
+++ b/components/custom/styles/default/RadioButtonStyle.qml
@@ -0,0 +1,34 @@
+import QtQuick 1.1
+import "tools" as StyleTools
+
+QtObject {
+    property int minimumWidth: 32
+    property int minimumHeight: 32
+
+    property Component background: Component {
+        Item {
+            width: styledItem.implicitWidth; height: styledItem.implicitHeight
+            Rectangle { // Background center fill
+                anchors.fill: parent
+                anchors.margins: 1
+                radius: width/2
+                color: backgroundColor
+            }
+            Image {
+                opacity: enabled ? 1 : 0.7
+                source: "images/radiobutton_normal.png"
+                fillMode: Image.Stretch
+                anchors.centerIn: parent
+            }
+        }
+    }
+
+    property Component checkmark: Component {
+        Image {
+            StyleTools.ColorConverter { id: cc; color: backgroundColor }
+            source: cc.grayValue() < 70? "images/radiobutton_check_white.png" : "images/radiobutton_check.png"
+            opacity: (!enabled && checked) || pressed == true ? 0.5 : (!checked ? 0 : 1)
+            Behavior on opacity { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }
+        }
+    }
+}
diff --git a/components/custom/styles/default/ScrollIndicatorStyle.qml b/components/custom/styles/default/ScrollIndicatorStyle.qml
new file mode 100644
index 000000000..8e8826cda
--- /dev/null
+++ b/components/custom/styles/default/ScrollIndicatorStyle.qml
@@ -0,0 +1,18 @@
+import QtQuick 1.0
+
+QtObject {
+    property int minimumWidth: 12
+    property int minimumHeight: 40
+
+    property Component content: Component {
+        Item {
+            Rectangle {
+                anchors.fill: parent
+                anchors.margins: 3
+                border.color: "black"
+                color: "gray"
+                radius: width/2
+            }
+        }
+    }
+}
diff --git a/components/custom/styles/default/SliderStyle.qml b/components/custom/styles/default/SliderStyle.qml
new file mode 100644
index 000000000..d32f13eb7
--- /dev/null
+++ b/components/custom/styles/default/SliderStyle.qml
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Components project on Qt Labs.
+**
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions contained
+** in the Technology Preview License Agreement accompanying this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+QtObject {
+
+    property int minimumWidth: 200
+    property int minimumHeight: 40
+
+    property int leftMargin : 2
+    property int topMargin: 0
+    property int rightMargin: 2
+    property int bottomMargin: 0
+
+    property Component groove: Item {
+        opacity: enabled ? 1.0 : 0.7
+
+        Rectangle {
+            color: backgroundColor
+            anchors.fill: sliderBackground
+            anchors.margins: 1
+            radius: 2
+        }
+
+        Rectangle {
+            property real zeroPos :  positionForValue(0)
+            property real handlePos: handlePosition
+            color: progressColor
+            height: 10
+            radius: 4
+            anchors.verticalCenter: parent.verticalCenter
+            x: zeroPos
+            width: handlePos - x
+        }
+
+        BorderImage {
+            id: sliderBackground
+            anchors.verticalCenter: parent.verticalCenter
+            width: parent.width
+            border.top: 2
+            border.bottom: 2
+            border.left: 12
+            border.right: 12
+            source: "images/slider.png"
+        }
+    }
+
+    property Component handle: Item {
+        width: handleImage.width
+        height: handleImage.height
+        anchors.verticalCenter: parent.verticalCenter
+
+        Image {
+            id: handleImage
+            Rectangle {
+                anchors.centerIn: parent
+                anchors.horizontalCenterOffset: -1
+                width: parent.width - 7
+                height: parent.height - 7
+                smooth: true
+                color: backgroundColor
+                radius: Math.floor(parent.width / 2)
+                z: -1   // behind the image
+            }
+            anchors.centerIn: parent;
+            source: "images/handle.png"
+            smooth: true
+        }
+    }
+
+    property Component valueIndicator: Rectangle {
+        width: valueText.width + 20
+        height: valueText.height + 20
+        color: "gray"
+        opacity: pressed ? 0.9 : 0
+        Behavior on opacity { NumberAnimation { duration: 100 } }
+        radius: 5
+
+        Text {
+            id: valueText
+            anchors.margins: 10
+            anchors.centerIn: parent
+            text: indicatorText
+        }
+    }
+}
diff --git a/components/custom/styles/default/SpinBoxStyle.qml b/components/custom/styles/default/SpinBoxStyle.qml
new file mode 100644
index 000000000..d42267d8d
--- /dev/null
+++ b/components/custom/styles/default/SpinBoxStyle.qml
@@ -0,0 +1,73 @@
+import QtQuick 1.0
+
+QtObject {
+
+    property int minimumWidth: 200
+    property int minimumHeight: 25
+
+    property int leftMargin : 8
+    property int topMargin: 8
+    property int rightMargin: 8
+    property int bottomMargin: 8
+
+    property Component background:
+    Component {
+        id: defaultBackground
+        Item {
+            opacity: enabled ? 1 : 0.7
+            Rectangle {
+                x: 1
+                y: 1
+                width: parent.width-2
+                height: parent.height-2
+                color: backgroundColor
+                radius: 5
+            }
+
+            BorderImage {
+                anchors.fill: parent
+                id: backgroundimage
+                smooth: true
+                source: "images/lineedit_normal.png"
+                border.left: 6; border.top: 6
+                border.right: 50; border.bottom: 6
+            }
+        }
+    }
+
+    property Component up:
+    Component {
+        id: defaultUp
+        Item {
+            anchors.right: parent.right
+            anchors.top: parent.top
+            width: 24
+            height: parent.height/2
+            Image {
+                anchors.left: parent.left;
+                anchors.top: parent.top;
+                anchors.topMargin: 7
+                opacity: (upEnabled && enabled) ? (upPressed ? 1 : 0.8) : 0.3
+                source: "images/spinbox_up.png"
+            }
+        }
+    }
+
+    property Component down:
+    Component {
+        id: defaultDown
+        Item {
+            anchors.right: parent.right
+            anchors.bottom: parent.bottom
+            width: 24
+            height: parent.height/2
+            Image {
+                anchors.left: parent.left;
+                anchors.bottom: parent.bottom;
+                anchors.bottomMargin: 7
+                opacity: (downEnabled && enabled) ? (downPressed ? 1 : 0.8) : 0.3
+                source: "images/spinbox_down.png"
+            }
+        }
+    }
+}
diff --git a/components/custom/styles/default/SwitchStyle.qml b/components/custom/styles/default/SwitchStyle.qml
new file mode 100644
index 000000000..35e6f235e
--- /dev/null
+++ b/components/custom/styles/default/SwitchStyle.qml
@@ -0,0 +1,71 @@
+import QtQuick 1.1
+
+QtObject {
+    property int minimumWidth: 80
+    property int minimumHeight: 32
+
+    property Component groove: Component {
+        Item {
+            opacity: enabled ? 1 : 0.7
+            Rectangle { // Background center fill
+                anchors.fill: parent
+                anchors.margins: 1
+                radius: 5
+                color: backgroundColor
+            }
+
+            Item { // Clipping container of the positive and negative groove highlight
+                anchors.fill: parent
+                anchors.margins: 2
+                clip: true
+
+                Item { // The highlight item is twice the width of there switch, clipped by its parent,
+                       // and sliding back and forth keeping the center under the handle
+                    height: parent.height
+                    width: 2*parent.width
+                    x: handleCenterX-parent.width-parent.anchors.leftMargin
+
+                    Rectangle { // positive background highlight
+                        color: positiveHighlightColor
+                        opacity: 0.8
+                        anchors.top: parent.top; anchors.bottom: parent.bottom
+                        anchors.left: parent.left; anchors.right: parent.horizontalCenter
+                    }
+                    Rectangle { // negative background highlight
+                        color: negativeHighlightColor
+                        opacity: 0.8
+                        anchors.top: parent.top; anchors.bottom: parent.bottom
+                        anchors.left: parent.horizontalCenter; anchors.right: parent.right
+                    }
+                }
+            }
+
+            BorderImage { // Rounded border
+                anchors.fill: parent
+                source: "images/lineedit_normal.png"
+                border { left: 6; right: 6; top: 3; bottom: 3 }
+                smooth: true
+            }
+        }
+    }
+
+    property Component handle: Component {
+        Item {
+            width: 42
+            Rectangle { // center fill
+                anchors.fill: parent
+                anchors.margins: 1
+                radius: 5
+                color: switchColor
+            }
+            BorderImage {
+                anchors.fill: parent
+                opacity: enabled ? 1 : 0.7
+                smooth: true
+                source: pressed ? "images/button_pressed.png" : "images/button_normal.png"
+                border { left: 4; top: 4; right: 4; bottom: 4 }
+            }
+            Behavior on x { NumberAnimation { easing.type: Easing.OutCubic; duration: 200 } }
+        }
+    }
+}
diff --git a/components/custom/styles/default/TextFieldStyle.qml b/components/custom/styles/default/TextFieldStyle.qml
new file mode 100644
index 000000000..38da6b0db
--- /dev/null
+++ b/components/custom/styles/default/TextFieldStyle.qml
@@ -0,0 +1,41 @@
+import QtQuick 1.0
+
+QtObject {
+
+    property int minimumWidth: 200
+    property int minimumHeight: 25
+
+    property int leftMargin : 8
+    property int topMargin: 8
+    property int rightMargin: 8
+    property int bottomMargin: 8
+
+    property Component background: Component {
+        Item {  // see QTBUG-14873
+            Rectangle { // Background center fill
+                anchors.fill: parent
+                anchors.margins: 1
+                radius: 5
+                color: backgroundColor
+            }
+            BorderImage { // Background border
+                opacity: enabled ? 1 : 0.7
+                anchors.fill: parent
+                border.left: 6; border.top: 6
+                border.right: 6; border.bottom: 6
+                smooth: true
+                source: "images/lineedit_normal.png"
+            }
+        }
+    }
+
+    property Component hints: Component {
+        Item {
+            property color textColor: "#444"
+            property color backgroundColor: "white"
+            property int fontPixelSize: 14
+            property bool fontBold: false
+            property int passwordEchoMode: TextInput.PasswordEchoOnEdit
+        }
+    }
+}
diff --git a/components/custom/styles/default/images/button_normal.png b/components/custom/styles/default/images/button_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..e54f1acba8b1ace3ba8cc456d6f457634d75b085
GIT binary patch
literal 877
zcmV-z1CsoSP)<h;3K|Lk000e1NJLTq003?P000{Z1^@s6owT}%00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01b)&01b)({Vk(N00007bV*G`2ign*
z3>OJy&2=>Z00QkvL_t(&-tC&dOB_KI$KSi%J@<AcxQFC&UZKH4u-m`Dn4}gFEETQ_
z#KwS)AT~CZNnw*FO^W;nYMWGPJncmkB(l1jxx4-0IlD72MLgq~Kfn>@3lEklzh6G@
z&0`0B--r8ZwOTkaF;Od*%MNHgy7D|vM@B}1hv#PhBM1V=ah&G#^z`iL=qTE@tzA<<
zoO7ew?Up#_yGfFK@jS107hDhoj_bOg78Vvt>+9>ouIt_a0N1uDAu~ymp`D$bxxKx;
zSB$Zxa=FY+0075vnlm#q>E`BUHHxBdK@haHU+T!V?Psg2tFu>ESHrDV>wO%@AJO-H
zh~xO{{{DUl0N>Bf&d#(|>Z#Fa)bl)_TV7uFh-lG_qR6XMDp0T2OS`+fhiRG?+9vgM
zad8pO&(FUpiejwW?b@bgSr#G+DJ5NAUP=HcX`9rP5P}<qA;-tZ&AVHrloFC8L2Zw^
zl2ZP^4oE4n*XwE8)DEshL^u!}5n-C9nz*M%oDc%zIM&3e9UKx7hG96+DxuTqXyVkq
zoFEbXBaVnb2!UyuYT^_R4gdyb91;=sdOb~?!XhFVAg-Tgr_<5IDXgL>aNt&X+bSWB
zV@=#snsNQZBuO-J>Ia92IJn1g&NXq0?{P$gLI}LOoD@ZYj4@4|;xn$lgb&QPEXy=;
zPhiFkv`Q&u2>=XjkJ7EObhpO|AvhwML{xa5S7wX}ZIOC1O%n~n7!pF5*Vosg<au73
zh~VVpByBdE<G0l5QmmGimd1{ck5LGb)M~ZNsMqU|=lS!4gM-G}+S*Ibd3bbml)>L0
zs=5@Y#l^+i%F4>yt*tFLilRf;b$_7m`@k5p5%F`Q(U2P(8?suhLY8HjZcvY}N~KbX
zqR8Cd-Y%b>o?7j8``zT^WQ6?(v5YZWO8Eg1Ut5+1mSst8n-VL4!8wPbD1I`=cBZDL
zegOdB!<Wne0O#lDFAT%bFJjdQ?j{Vw-@fnP+&}*VwN;r8$j7=a00000NkvXXu0mjf
D%w(RS

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/button_pressed.png b/components/custom/styles/default/images/button_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..b7a63f1ad49c5676266eaa1a2e54e41a3aa02e6c
GIT binary patch
literal 803
zcmV+;1Kj+HP)<h;3K|Lk000e1NJLTq003?P000{Z1^@s6owT}%00004b3#c}2nYxW
zd<bNS00009a7bBm000e&000e&0sSqbNB{r;8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10-#AmK~!jg?b^>v+h7<6@aK8oH;HD+MmlC|CX7u*@Rs9_vcZIT
zu?KsppqF}_`#T20+;K=Qg0~&Kj6n~>>tNE0BJ5JAzo<4{L#55zH`&G3Vr4rFOat!+
z0wKA4;eqe_z9i^44)ojK-^a<x$tQ@Yf;0@;rfF7hKV;pT^Ye3E*Y(w@si`?l)2N~-
zc)$6iyKv4)qtSpUioS+n=vtQ50=ORB_0T>}OiVmjT3UKR2;r?(s}*l#2>?LTG!+p?
zx3{-*l}cqU2!gz-ssRH4&~<&)wryNqUVgT@x%s73DtU1SmTt_>&OTaSUw`Ae?&Fh_
zlXt09>O;3GUuLt}^zQC%u~aG@$C^?aaBy&NwX?JHEtku^-PqW84FDh5<>jTNsw%T>
z+bkA~zW_kQ9aI{$x3^bbTU!H4>BDNZI?5D9Q2-ze!!T?%o1M4=N_P`NM4a=0QmQe=
zl-{lq5di?A_@YVwf{4BOuv_os;1Z&La1qGC4ZGfqWK|}}^^5>OR%K$zs!W!_s_c6q
z4XOUBBr)cY{)60{B+H%WIJw3ph+N|mq}z&wkVsZ#vdF4TFnJtE8bs_J378NfV2n{h
z2%4rzeczX#c7_n86d7Zh5CWUcrXZGO)uSj1Pft&4i;IiT;ifX>HAL6K!ot(Dv$H@5
z;iuE-D>^<t4xIC`qobp-m6a7o2yuLPc=-Eo)0gho{QSI~&*!sSTU%GPTJ5J{7~j!x
z9Pm7E1Q9=HG8wf{D5MO-AnkVBk2|mgpsK3j`#!p^+bEaI;CWtQdV0Ew-5+8-&l?d!
zyeEXbQWS+KiXt~ELx6KmIOief{71cB|1>i*a|{50xBp}Y0H{<d8A|EMy{D80bUK~(
h#l=O<ah!Jl^FO9oVyo(%M@j$y002ovPDHLkV1m<CbPWIi

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/buttongroup_h_normal.png b/components/custom/styles/default/images/buttongroup_h_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..bae593818a783187e7b5ff5fceddf99a0c9bd58a
GIT binary patch
literal 482
zcmV<80UiE{P)<h;3K|Lk000e1NJLTq002k;000{Z1^@s6-}lKL00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01b)&01b)({Vk(N00007bV*G`2ign*
z3>q$VX}%Kx00Cl2L_t(o!|j<dZo)7WhW|$#D+&`EBP$~pVC~2edZ}Kc17kOCzzr%E
zM1>+*lsH&%-b)8sDU>89c;8~rpZ@pTiD|W3;g9`(kHum!x7OxR0N|6>>-Bq<We6dl
zyDC5k0Tg500;mDlf2#smbGzLRr_*VxE}q$JHm^oR=y*JSsg8b(wHD5~Z|^;;jz`+I
zO^k@N=kr+rkSckEh}eh-%Cb~BLn9_46hfG&iUC1w+miQQ6Eq}<ndy4Hs-Te(!{u^O
zL1PK>-fIW-AM^JP3L$8M22Ogz%%meWK4Q?49vLxarm`%xgL+8Q^xi>rU2B4d1T{@V
z&N&s-!*n_&!_26vN(BvdkcdnGB&uWhTP&H)W~p;d{|7xM$QUAG=UnV|ldAc>B@#7#
z3DP6KlOWpdc5iu}=T%iz0MOkl04<lxj~L@5O;Z7Y?p^^*mSr#9hr*&L=1G$1%i*2F
Y4+kc~lX+oNo&W#<07*qoM6N<$g82Hw>Hq)$

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/buttongroup_h_pressed.png b/components/custom/styles/default/images/buttongroup_h_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0c97fd587a87f1718c7199153cdb0cbab74429e
GIT binary patch
literal 386
zcmeAS@N?(olHy`uVBq!ia0vp^IY2DU!3HE}I%aJFQjEnx?oJHr&dIz4a@dl*-CY>|
zgW!U_%O?XxI14-?i-Fp^K$!8b?qUz1AbW|YuPgg4ZaIDfm4G@yZ=fkmo-U3d8Ta1a
zbj)fq5Mg;xsg}9v<faR2XK+8UvUORw{ne`Qk4*O#EX;O3^M3z|CUFfl1NjcenA92V
zLY;<>OwMoix%@>-Nq>P@%KN|Pzc#iA>|@BtUVF+iJbSItF^=!A>XuGPj19MVUU1Kp
zLFe=*-h}63TXSWO^YcC^Y&m*BYWb8~UpJ;D%)P+S_IS~;t5Hv_gjQ~z=rOm)h3(jZ
z7xN2LHYFZ8(4o9B`cL9B4;3~yo*sGGBW;4x*GvT)*%s*eE^eFqJaH=TYv%KZt#T!p
zU$0G6Z1GP%!^f~x#PWK{`k+$@J(Y7_N3G6y|M&OTrBg1=4mwr1``z~3Xg|%r$0Rlv
d*H5%zyg4Us*UdJ)Oke;pc)I$ztaD0e0svIHpR51?

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/checkbox_check.png b/components/custom/styles/default/images/checkbox_check.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2f1f02d2d91b719209e71dd0d26adda9182962b
GIT binary patch
literal 557
zcmV+|0@D47P)<h;3K|Lk000e1NJLTq000vJ000#T1^@s6qzTp000004b3#c}2nYxW
zd<bNS00009a7bBm000e&000e&0sSqbNB{r;8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10jfzvK~y-6t<*h?jZqK=;OE}G>nBl2gi@(LrBX#Bkq8MQk)T6_
zN~fb0twu;BN;C>0k?7=G*+N4rgoF*t?*01|XTF<re{Ak<OgD38-t)dQb51Lz<bPRb
zD@9dRwQv9*P^XlJ(B1-28&~iS*RdEet<A`+s%jCBaV$bT9Kmb!=VlhtE)+oU7GJTz
z=49^1&BA|xbNGyUZm{Ud4eX21N8H8=R?$x>)$=mjfs2KID}a7t9Yc!Mh@OCyQauqr
zD$9gryb4C^7&iIsqTnPBVWAmySQ}>w|0#Y4(4f4yQxx3AUfjdgs;bt4{vI5TyaAqI
z4ZRWwI>Bmx0FlSv!ex1nPGDP{y^*KaZTeJNBd5lrB7PpHupOt1c*Ck6HDlJu{De!9
zbT(pl<h~pXe-+Qo=+%f>1pD|S@6vLd?ZU&53@`8_q)$m4$&6Ru#do=9-)7|A4~e~5
z5=UTR4d8nm$Cu*lC8~`ij)6tOAZ}j@z-PE7PxhB$+h^I-7Zj_~k)O~``A6u=i`q>o
v4gLi-^)@F4vLg3!><!M%Y=YtBB^%mbFa(~Q2<4OQ00000NkvXXu0mjf^T+ez

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/handle.png b/components/custom/styles/default/images/handle.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd8fbddfbde6a43773e32fa34ab4f02c7e88ca16
GIT binary patch
literal 1529
zcmV<V1qS+wP)<h;3K|Lk000e1NJLTq001KZ001Kh1^@s69@(>500004b3#c}2nYxW
zd<bNS00009a7bBm000e&000e&0sSqbNB{r;8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H11$Ie9K~z|U#hBk~6jv0-zvs+M_D6Q(Zn}+Yt1+6NP%M?=gPLF{
zjXv~ET%?HjmxvF>f5E(nAc$BLL}=+lnn)?Jv?P_9(vSv8vm2W(ChRYFCOf-3w-0k~
zcCseACRuvmGJAJt=6v>?`{R2q2_f*lMnt4O%BD=n2C;(|Q=`vF00O|WY4WPRS0E06
zs=PXqt05=vgpm-+x#4NL2TYj)r~oJfu;u3}0Ows$Z-pTu1<?Y)55NZ?0H7B@HxU`J
zSj?yEI<2j(t=qQk0C)*t9za0?l>n?uu&NNkd2bjAVo2vf03T|aHaIvqc;Lc?3(=D&
zPX+>kfUi=i_yK5!VXSMKW<7iM%zp6TL2i6}Je|+yrvWTU5EFm}pu8Q>mM{{e1wbo+
zHUMAr_V%{lzJ0rgh`LPEGyn)@7MiAknZe8;A}})r0s(|Vq2$%8SLg5Fzh4CKBY-S`
zqHOk7KySc!KtcdwMD*3z*qC<W#EH+->2!>lg>){62=y?Urh$lvnGp(wOv|!<J9Fkt
zzECLq0$^Ffyxt0k>p)1RrWHU(M@Prk6B85N-QC?^uB@zl06-9tAR-~}um2<JDu_s!
zrWw?Aeen77=L17SLn8o=$al8_FsSYY8<CMe=<>#PB1$}Y^5keXo9$(0N7FPF5pPPi
zZ8Ab&W(XlD7K^Q%I(6!gR4O$NU==`KMyaA^nKv>jJwX5?V`F1%S=Ld=wW2=1jT#Yw
zh(s=zJ1{vp*+E3Z9zQK!2KGcngFAiW{r&x+<HwJGW|}6+knfab14sxVn0esFjT;((
zPv9;SegK+Em!eW*#YaSgw{G3)Nu^S;-9prxWm&!}SFU^-kH`Dr4hf(1y9q|EDUoyM
z&K)cki@lJ8buVFvNE8Z%1J|!#KLp??+%y@AgFVZ=0bn4JNVMg0Io|82C=)_pWMst0
z%tuh$VwmKbqQ;BP%m<GhI~Igz_iY9b5ykuZ`l7P0OaGhF#F0ouw{5$%i68)gYPA|1
z7#Ij+vkD-u1mIXK<}Z~>zGi{|K&4VaPfw2lKmn10f$Sh04!6jSuc;=4!2bRF4Y;#u
zL!c=b0RY)-wxsL&db44O2+PaMHr!o&V|=ow<E*Z(mi&Hy(_wU7$HKyb4R<?G{)LK+
z1Hj4UayB!+#%5i+=Vlm2er|3qkD5$%6pVl?3o8JUGcz+L-W1w<X;dzk(~FCXS=m>z
z6fAd42d+e%zjyCmw!OXG-bvNah%qxBKYnZhcp)Lmkowr0rZRxS)2C0DiD-_QNeHp0
z(GfyWI2>NOcJ10r)Z}Pc`rkC0lz5)Hbm`L4;lqdj+3V<pLZRa5=;(AlpZ^nXR7%os
zP0z?wRpF}mSLt**_vq21nSJ~A*+PhhYpd-{2mxlMOeXXD&6_uU0RBR)YN&1{t{l`<
z{N(89s8%YK7Ia-#tMraRh={`B@ZZD3!+8J`aHC;Le;YcOJr4=EBin*2n7>OT60dCA
z{xuqnnleHSLkS@ugdoE(s=;7zc4%nmMJ|{78E!pQlzuiO=O!2rkfL5QP4k=c=g<H9
z@ZrO6ySlnkYEUbv`t+&3x+fBetR|Dm@B8}tl1ocVKfo>URJl^FuQ0c(n^YAUgj=$l
zjz*&&-MxGF<9IyYna}5=<#Kt;y2&sMYHMpN0(g1(^5yyI>1hkVPcqs?`A16))lD9t
z`ie3F;B;qaXY}I5i?Oq3&xYdhxMmoJpNN=<%uFUzotl~|-??+=)$HtS#&Mh(0RLh)
z6=fYzeXVT(I0T>vZdoIk8II!++!>Mtu!!0kvin-w1N5#_i2C!H=A1%o0rmf$&%6Z;
fcymMD)ydU=y1<_V8yB=W00000NkvXXu0mjfA3n)-

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/lineedit_normal.png b/components/custom/styles/default/images/lineedit_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..2253d33f92e4a11742df1633473bef7695c5b6e6
GIT binary patch
literal 794
zcmV+#1LgdQP)<h;3K|Lk000e1NJLTq003_Q000{Z1^@s6a(2<T00004b3#c}2nYxW
zd<bNS00009a7bBm000e&000e&0sSqbNB{r;8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10+&fdK~!jg?b^?4(_kFO@z0Yy-O{wlmfGSnhttA9D5$C0qhy|X
z@gV3ycIwXl5&Z}D4|w(#ytr#GUKDX;mx&04l`xHm+Dd-e)wGWXx6H|Oo=gMJ3j!gh
zFT8o4hrmM&!vFx-woL#m11QIFTpSDrGPs#gDwQHiX#n60fRFWhodEy^0Nb_|-}kR?
zZf@S~bUL@gFuX9COr~iL%$*QLQIKW1zrMcy+On)ywr%g#>vf+n#^$3ax>Kvw9`<^@
zivV5#*at99d1mf}0N@gU`?{_Nj^kLA(j5w5bz@`WTCdmB0JH&oPjgD{j|KqtT-SZl
zY&LIpI-NdYj5SK7(u3h}_!7X|v?t`wbwyE>mgjlTD1br`1p3_E+`c49EbYm-zne~{
zP8f#EqtQsFN8hL<N#n)EMILYV#ZeRy&-29Nc#tFs3kwTr4#oYWgM$MAN52Y$5CCAJ
zDDst;A;&9^<@0$~E|+<{3`w?4LI}&{ay(v!&|ltpyo^cW$+FB=R#tet3`x#BK@gZM
z%RF9&oI3N0#UhWFA*WWJs;WF*h9oOb5Co=a8jqJDNxac$1mE|0ybMXUO+pA;T3X`q
zGUU{@S*=!iybMX=MN!1~wwWyy02pKA!^6XzX_`FVjBB^sB7mu?suKzzR8{p;zu&(K
z;B(5eap&0D+FC6X3a%tckpSRpv)TMG9*-ZHrYQhm{F&V+2!h9rM&mtzAz_To1Gu%e
zwsx=E?P>s?0_YlsF*!3m_uuXA?h*i(0km{oR~^TBPAT0XhGD?AZ3RHB)oR_?-rhEX
zAgIJ~{4M2~xg(TPDWA^|P1Ag5S=Jj$>CbzcXWf|geP3~1S4nkZE>Wpe0!`CA{B~pd
Y2dceVpMfcWg8%>k07*qoM6N<$f-1XcyZ`_I

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/progress-bar-background.png b/components/custom/styles/default/images/progress-bar-background.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f30927ed8c34581a96edf764c98e4a687352bbc
GIT binary patch
literal 484
zcmV<A0UQ2_P)<h;3K|Lk000e1NJLTq004{t000pP1^@s64>&}l0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzhDk(0RCwC#noUl^Kp2L<=}f1zSQ2(5
zO~94j!MJJMcmQwW2{-^OJcnn1jnR#9>B2Q68W%tW#s#H*GuB2z{b9}fOx|?TcJ<}S
zH`5<67z_yPFKL?YbievGPdGi!X)y<Tz;HPH?eds&!?|R!?3_f=VU9U>^?K9{!;qAc
zs3f4(DkEbIEf&j(Z6qwsqw6qAseUc2H5-kXq=YQs6JHbQK$GWrO=I5seCpf@vtF;y
z;`o4k-zOo23jleZTUjXPM#5btE%z`iOrTjO$rm9DC}9_@G^Bj%h~C)rdQxya6bWoP
z!z1Uh^^}CA2>je=M1?TL0HCVNYzgDe!52_%Oo>;toE%jFe=JLRDNGOqOS3en3aG@s
zyt9s!!X!y@Kb_8KKA+piCsYVHtP9qO>11Xdc_{ZV?RLAXwZ0mSM#;<bYn)}7Lb-sH
zaur3<Tc>k4Znaunw={iytxnVQgbx>-BTgOV0?dN*#JT3&ZU_VRlU;vr5bo740RQAe
afB^tSnro-)atLk!0000<MNUMnLSTY)Ak$L-

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/progress-bar-bar.png b/components/custom/styles/default/images/progress-bar-bar.png
new file mode 100644
index 0000000000000000000000000000000000000000..446c13f2c20c5b8ea4e8e3cfbbd689847d9ad5e4
GIT binary patch
literal 548
zcmV+<0^9wGP)<h;3K|Lk000e1NJLTq004{t000pP1^@s64>&}l0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz#z{m$RCwC#nmtMbK^TU=nVmI+_`{l*
zxE5B5h@QYo!2?)$0}l{VNJyzgAXtQ0*m(zUU}vj>c48rD$VNyJO^lnFaVAbgFrwDJ
z4}3ejQ@%WW^TUc-tw#BLo)OWg0{<61s)l0lVzD@%%jFI@=WC3y5P1QubzLcS)@U?#
zE0xNfnNn63uT(0n8d**=3sEpJ*CLUKkrtqS&!_f7K#w=sRun~><#PE_n0b*-r}r~U
z_kqY=Q(JXOb^1sP5NCqKT#{zQN+9Lzo|)R_=HUw=*46X{y~;Kz4OzfD)&=W?49>~(
zybbG$6~;4rmPz6-NC<q>YI<ZGNm*AoPD9`iFfkNHDUCS5uY`GDucSg8;72}$kq`#_
zK^Q4x?GeMW1V%8p-z7N|MoTGg`|ZpkOEnM<`07h1OV$zlYK4(e6jj5i<s&A|p()uk
z$Ea7N1kA>EjHo+9y0t{jX7kXxVtY-}RH{%YY=vRC<NN+9=X@M#0j1Pa9LHDndi}Us
zt)7^vXXcirgcB#>zHvVT?1t8!gzVLS&s5ir!fj@HZnW3Eo)ZQD<-F*-lERrJKiM?w
mEa))kFrPck;D4Am0R{ko|DwO@@+_GE0000<MNUMnLSTYg^zu3Y

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/progressbar_fill.png b/components/custom/styles/default/images/progressbar_fill.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f8778969a849127acc0d8e83c4ebd6aba53b903
GIT binary patch
literal 992
zcmV<610Vc}P)<h;3K|Lk000e1NJLTq001xm001Wl1^@s6Nzu!s00004b3#c}2nYxW
zd<bNS00009a7bBm000D6000D60sT^Gw*UYD8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H116@f(K~z|U)mc4H8$l3#Gq(l;iVO&_g<=pwvP6+zkSa<d(WIue
z($P^-($Y}#BWUvvQcy*rA%r4IB#_b}Pze6G-MvYH*E#U{*t5?Do^+Be&&}Mt`CK1~
z2mpYHN;5Mv@2l17+T7gSJP{!dC+7q46po^3Ae~1?M}J8~FgZE-W@BTcR;$%?rBeAh
zJ3D)EUpVfN#{<#>zdM~?a!L9Mg~H<c`g%zb(aPrL=BMrL?PC!+27t@U%PtK;5O~`1
zhJQ#CP%IW-04S+SrShRxt6dvoz9EG<Ywd$dGdk(Zej=hMA^@bS)#~eVx%{KiXmFCC
zZ$1NnG3G%TrIi0ura(k)9VnGbFPZs|wYC={12Gl12>@XjX1b|YRNE1NA|galBq<K$
zg}(InN?mI$hzJS*8Dm&$%>cm60~Ob((5V6U#YG_RNCZJJ6hb;FBqC(3rD3H|UV85n
z(Jo>rXGCkw!(uBBIK~}}F$91+Ddes}4UMXX?xc{2<nr)w#e<;N?1{HjC!zpAYfWJo
zb{QVR`rwO165`9BwU*(!kchB|bWLKP$(m(S_lqPV<3&uy7}8qz8~RN5Jrva>LXy^Q
zV+@!XE&{pat`9uU0A9~wtz{7**GAbGleo;KAxrw?T~D1N)>=!e)slL>E&xy{6ucb?
zg1|d!z3Qpo8gc_t-Q3*N4-XH&@9*#b?nlvMVQ+6wUtC-)xEhc!44>>2j$?d$+<lCI
z_8eelA)<jDaII~aXti1Z{x^esjz?|eK|)qriijNh&mx5!m>EPQojEYd8W<ZJ%O%y^
ziEQM^gDls66@X`%Lb&Zhl4}>r8$MmF;{duNFp}LU4QZshgOl5ZI{h_<Cl`@8;x*7K
z0#6#uw=0_hAOkw^D5)kQ!px*{I8Z%G<cLT_M3jiQ!SdWv=(YyV&(E(H7Z=OTX7g;w
zHd9k=Vq&5%rRwzb^h89~rl+UBUR_=Jzw^nC)Cf15%}mOo_BzVe+Aq7iyAuZo2k(}b
zmxH#UCx0<Bm|2vF{34>yTU%QncXoDO&Ck!DH5!fcdcCgid+qy9%e6QUxjXvO{#dwg
zdueH@3;+~+OSu5xZLwHfSzTRSn3|gEI)(dotSE}S1haI&B%LQGC(VDYyYyvoiO9+T
O0000<MNUMnLSTYx$-1fl

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/progressbar_groove.png b/components/custom/styles/default/images/progressbar_groove.png
new file mode 100644
index 0000000000000000000000000000000000000000..263ced8bf3a8430f0b725678a78248fc2a23a72a
GIT binary patch
literal 492
zcmeAS@N?(olHy`uVBq!ia0vp^$v~{m!3HFyKYe=-q*#ibJVQ8upoSx*1IXtr@Q5r1
z3WtL*<KLjn?La}v64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<_&Gd*1#
zLoyoQPTlBt*g&A|z0UF+l>;IxlNxk`{<Jh$eNeEG>^OR}>(GrEGRz(hf+C{k|0dtr
z?%MUv{_gY5H!Zin*_EfNq^@-7V&VhltFpFd<`{mqI=yKsuVT#h-0J6h>wD%3@09Zj
z`*LTK&iU>|J2twMJlng!Kd_{G<*AN&S53}3&wIXn+xy?Vf_q(7S-)DSa_*ImAm>~C
z<QK0KuUx;#mm)8zDgSt7?&0S;8{f;XFj}^!@^)m>%%A$R4MQ0NqW|4CHEmybAV<!)
zzS{Vifyk9L`bG(UCw(^GlPeH>sciOH`HW55LY327ch`5ecbu3|$ei|f_NrA!mgG78
zbVy}bXw(oO>9B%FA%smpi<x68W6LQ9Ct`(@dn~=~wm7-Ca67yBm&V2~dzW&~;<?_8
yovF|77_}6rDjj#(;(7N5Po%-;&0D{H6Fu`SAiwmBZagq%7(8A5T-G@yGywoN3CJM;

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/progressbar_indeterminate.png b/components/custom/styles/default/images/progressbar_indeterminate.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ea46460b59830404ca61024da78ac8568a09b49
GIT binary patch
literal 1152
zcmV-`1b_R9P)<h;3K|Lk000e1NJLTq003YB001Wl1^@s6@WoB+00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00dwF00dwGbSnOq00007bV*G`2ipM)
z3=<00Y`GNx00aO@L_t(&-tAkzPa{VZes4SmY{6kCfm?wI$03k%T&NS5k*+|O28q8Q
zkcOTLA<?9up`?iTacvM%n!DzTlpIZ}B$t34WbUL0<N!93S$lV8UJAUHiOxQQXT9qm
zPja!gyq<5~`@Z+Rv5hk`Ge5@T@t@Y$*Yk|A_|VYM<7hPcDI!8ML|<QDrWw|$l!A0R
zeU?ln|GK=qd<_6;000C42!%rNxw*OT=I7__(b3V9Xf*n7m3tAicreD?z=#(Y7oVM+
zoIKjx+zjmP?Y%Hfa~}a<Y++$xd3kyHEfM`z>D_@qK=*>0E|Hw``vE1Q|6Nb7uC7jP
zZEgL4u~_W;-QC@%0|NuE>Rq4<NowjOR@;x$)6?g(v$MbR@$vC#!!Z7~EQ{5Wy=ozZ
zaIK0e(b~@ml~PuGZE$e#cx-I!OFle2{2&+%W=+#X7eSVQS(fEzR%uCSEkzp+hqJL*
z>;XqaP)d=M68#9QN)?fZ(pNWLr4(?^87CqXLNMF5nTrm<Rgl%F{t<S0hE*wr007*%
za2TMQ30{J%brZa>t<FAk=fW)s(sf@yC-OcRrId__kP{I~DbcoV*6P*jCwaZa0HqW<
zk5&Td78`Z2(lJWBc!9d~P{(~L**L$soqDheA#NlH0Km3wv@8pK1Q;t>H!p`Qo%=yV
zB?&?zVnoF5Guhr{QuY{l-OQ9ylCHJh>H$Isv~3$30qkQ7{7^#ctbCmXfHg=<O+{Nw
z06INDn<uVi0&K)_fKD^uLII!<f|bt!%y~lhnTJ>X#P5!-<brJ5rb3}W*Voqs01ylY
z*&Q~uW{{Pr>E|AzTNTQ&3L$QKKrWXv_xJbz+}POo2RhNPSX^8j%49OryqFlWEUPIF
z;kvuKYqogJ5Zuu^L?jIqa~*i0P-uwfcRPx5M0&rT(vZY<38%sHvW;uU&GTHUN^?LX
zdq7uLmtQp6v!Zj<f_w4d&C>8)?g2LpKtyU|3G!U3w7MV{s-$J5$|-za){)6?4XTx0
z)h!n!rTmb;?nu%d2f+IjZ8ZjTG}^@h&^Z_406=vnzz;gzbj4GWAPt9+9jU6LXt`3#
z8H}i%fP2kY&N&Dn6i=m6SB7Cc%;)p(yaeCV)6-T`H8L_{93LNF@x#NzKM?UrBog^G
zlgTKrz~}S%w$YzRB*FmTi)1qSHUI!uiA3V7?d|PP4h{}d=jZ1NI^mjBO-)S&cXoE3
zt*opJo}Hcj?0nGIlarI*E-fwDhGD!jP4j&&m$SS;?()y%J&WGn-mY*sJd#eQKVMs0
z<3~qFF9G09IoJUJ_@=+V|Ix(6gb@mb0v#gg3)3`ZB9S=FX0s^(_yvmplKc;d<{lzB
ST`dy;0000<MNUMnLSTZ$iWCO`

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/progressbar_overlay.png b/components/custom/styles/default/images/progressbar_overlay.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e351f965906de0e757a2848440af05727debb98
GIT binary patch
literal 284
zcmeAS@N?(olHy`uVBq!ia0vp^RzNJv!3HFM3)L?JQj#UE5hcO-X(i=}MX3yqDfvmM
z3ZA)%>8U}fi7AzZCsS>JiuQTBIEGZ*dUDN|t3g4a?V)7$)os=+cmF%ZE-;=UEc$mA
zn^c{#fMA5a|JDg>x7rGte#vD^lXDi|J#CIwdCAV%Zp=ZmpjfYmEk$QbL<-NAj1-M6
z6)7AdOh4IL9e*tdIH9f~^NEkE)5bY*Vzq`zP}^PRsFEi<y^%3mMR}_ncBy4Mu>IY|
zaUxuU>(cJ)u}xo?jXXDhyEEad_p-cChi9Md^SPVCdxBd;w6Z}-*<8b_=<b!n%BgCM
aYz)3e3iWZPyKI3zVeoYIb6Mw<&;$Te>SgEv

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/qt-logo.png b/components/custom/styles/default/images/qt-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..005ee5ca3204e0cbd3f9157477421e8d8e26a35e
GIT binary patch
literal 954
zcmV;r14aCaP)<h;3K|Lk000e1NJLTq000mG000vR1^@s6nP-j900001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igh@
z4>cQHAAXkr00TNnL_t(I%UzR8Y*kehhQGD<Ip;olT54M?R{J1?XnE8U0;#o5AYvzV
zA`@l6#DNZoAvhr7i-~byG=_m%V>Du-(P)ezAsUSu9%+EkN=uBjU>`#5ZN)zBy?vZ}
z_Hxkn_LjAWd+mR%_5Ewhfnx_7M<++RceI;5Rhx7}+N&7#Y;Y;`D=t?gtNW(%<D&_i
z%xy^4WM621cV0x6C<$pe`0%-=mZ+n-HN?eQyij!@;G2XqVlz(T2@x}4#lIB>mA?lz
zIdHi3)oT)V*1LUO)lysMFDr@wifU;Y5M)Ie1#mctU4$pgPqdgON@2Q^N4GtOvGC_q
zAGhX)@J$lWL$eDxNqT9F7>rHet<?bE7tWtq<igwE5GKn&1V!n-{1UyHANcibR=zv=
z6>pt?4o3`tDRwEswZ04=9QlYa6>@gy6P|phjlt0y9NzT`Wo9EyWi4!}ZUzBenbE94
zQ-WwCyB};p)$!xd=OpjR@k{^D_$I-oxdVK5q8nAq$^Bo@RN0KGD-m!|TTzc-$VXWU
zF2eUcMkmLx#u9`DuKzViOvJ_E@5x28fRqTJq=OJ6LaY(0im^g&F}pmXjks}pgo0b*
z%;5WEa(^RIB2e_c$W#z5@?EYb0wVY}fe~{TM1<_pEKVK12@rwUIm!}g02T^)N>^hw
z)&vZUPmdr7DL*8zX$p~}uBr}D{>_gUVI#V_PwQ<YHN(079st@JI`QI4+M7GbM_DH3
zZ}Q*l3@KaAj`B|G!-sI|Tu`NXdkwFBd5rPQ9iG~Dgg3fAW!Ki7e0}{CUd0SQ4WFiW
z>>_)&wlVK!5d<mkY|wpORouJs7ktk!JQ(rv6YufJ_Pw0yIZFRO7na*K!cx45!D7V&
zLD#t;B18p8Z6loc_;mmdwH#-6-F{*%;GE(~0&6@JC9tV6b2n8%@I8-)JsFOkewM+h
zUb4}&3abZIRUD3*^!?9!D>PL^WOct$#S4`A^lyB4<?5WZ{$yZNw~d%g+AsgZH^IQp
z+K!&5TVK5CJy3Jsan;2)V^`3Gmzqm@;ea4lYs1DXOYwaFLLqm@N|1Ye%QLx-&0YDm
cUcUw4f7bC$T}C^hI{*Lx07*qoM6N<$g6l%Ay8r+H

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/radiobutton_check.png b/components/custom/styles/default/images/radiobutton_check.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d433860694359f394b7a50ba847bf93dbed6606
GIT binary patch
literal 1331
zcmV-31<d-1P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ea000ea0W}m4y#N3J8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H11h7d&K~z|U#g|QQ8&wpBpL1u%sS`V?lhzG&qa;m20}U-ufkcri
z78NX5v1J7kRN@C9_yMd@7q9{$u|q;Ek=P*dAwVEV$|9i<+DHiw(4aO6b{%_W?qM-w
zGqGkI2UX&g?&jWe&w20HIqwx!rB4{344edtKn{?2Oo0}#3v2>gfbGYr^g-YVa27ZQ
z+=>I-i328)14d(l$72#Jz}|l)VB)~{#g2YEh-nulfCqpo@Dmw3l0_g7JP}V`&6?Z?
z3~&Y*2fiU?H_`}{fX9I)qAkA{7zfS)-vQhEMpQM~@~ZlbsusHX??o%B>eH%vB-w8g
zTpZvc@B>i0M=MX_Z{S)SqZ2oI1m}Rez^?~+I)DEBP`zG%7`PxJ1yx<L)-K+>dGpUc
zh};i&z;cp69(WS?l;};TVs38k6!4y^UIuU+rzs*51c3`UBC-a&xVpOfc@F{tTn4@b
z_Sys<Bf9aMS+izmXI~JJw_Mltip65i^E^bPGadv1^?Kbl8Vv#7ZZsONRjbvz8SW;C
za>b${I{VTA!LI=C77B%-N~Mx3l}Z?6_Sv|u%gD%xDV0iMjJYy6IQT)2UD${T7z3OD
zGS6;$dU^`DS}Ycw$;nB|<uYSqV+;%oq}mS*3@|!6np4$hXJ%%e??GY<IBtLnJy!3!
z?)#qSx#Q#G3=R$g5QZVGR(B@eH-|!@U_|7d`T6;i8D^V6#Q-C~?KF$o+1awHUK$=A
z_S)y&Y&O~2+QQo2$uXbLBO*E9_g@kbH^t;OFya#3fiT0*qkwf?*X-`@QmfSt3=Gi@
zg<*)}II5~=E0xM=;Fm757T_6rJUifm>$-k>^@j-#;CY@0Jmk9WSfx@qmS%6#Iuj_F
z?(3cbYc0O-cY*_m2qH2Jkjv##38bA(2dcUh1VOKHthHEcNvo<s5Lj#Na!hb2&4(c>
zwNBcg<2Z}fTCdq`5(Gh~`Myu9)#|J`OH%|v5QxZi01?S8EG*;_!#Th=zz%RU&B5yG
z>d(NPy}iB8O0!m*5*%x-r>fW5eap+s$xCz;*fB&YxRT~XRjsPN+-Nj3dA0{ZRjJi#
zzKDDrhT-+Ndrwu9=UD+Z4N(>x&vJI-#*L4F4{NnrtDje(s?_UstE#)!+N<sUFbum(
zd>Oc9h;qO-k@ibPv)Ozl48!lYx3|M)vzZy(_kDJDc6{IWx5F@eJq*K6F&Y{g`Xga_
z3iu1K?P@qkBos2sv53gb%*?C68zQ2f=ee%y8h{`OGzfy0wKfNQqN;C(VOUQPt5&Pk
z^|mWg$}#jQNT#NyE*fK=a~$W4s-6>(ysECmZK?h2+ECTq_4V}?{Ws7VqUXO)kU;bl
zp8|f2w<i;mlanRjw20)gY{D?KBC@fuvGIE%co|p#J|kAz-KsbbTmru009_~|&cwvT
z32SY^b=@K0h^n?k<gVj5b!+XdwY9aR3@;K%{Vzz!^Io!ik*H?(1rZU=P7r0_5#U?8
zWO=WT$wgqD=uY(gf$Zi5%n{xCuj%t+(uM;(NR%U1h!WOeFagXH36Dd6&64=vKBwJi
pf6ptxFp;)T!Y8ULRSxkz{|C<mldRe*zN!EK002ovPDHLkV1jikUIhRE

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/radiobutton_check_white.png b/components/custom/styles/default/images/radiobutton_check_white.png
new file mode 100644
index 0000000000000000000000000000000000000000..b68e7a6987c99020644efac3cde7f54caaee6382
GIT binary patch
literal 1310
zcmV+(1>yRMP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ea000ea0W}m4y#N3J8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H11e-}jK~z|U#h2e}990y@Klkp;WY?tWZjxPhyD5mERjWZQ3RWmS
z6n*f?SDzGOpnrhqQ=yP&>4QEg0pA4iQSe3Z2T@iuTMJG61w!Ngm{ywIB)epH?#%V!
z&c?}hX0nxnUl^FVKhF8yGv}TkLTk;0kU$AI1)KmJK!kG|7y`RM6SxfolL!?P5Xb^&
zfd$}Js9+~l7=;7Og#?QsiA~_(zY>t4;z}s!uj81G;WY3#&;Yhbut*Yt9PmQ8`S+yF
z6F>rIfHLqsG1iD9Pyn6>>KK#X50rr=;0K^{WJYTpeR5jsSG3kMW8?SZIia<FS!<n*
zj>`y_3~(O!3E00+Cy!zexEAU-)EoT;OF$p^<2XsK>rVT=|8ypkIS0&Wt?N?CjZ&%P
zPC(>Qzy@wa3FLqmfiE$4Iu?yaV^K=ECWN>M;QRhSYb`9xvM?6>6L_;+E`OauKmZqk
zZ-Ijmf#)zD-%Q%oZnxh6-uFDu?)UqSQi`YpTb4yOn+>wrtN=dHTEA1NRQd_xPGe%l
zh76e((v-Jatrg&-UavPj91fjaE_c@&r4;-7`?A~ZiXaG9gb<&kSYbOPASLi1kofP~
z?e;@Lh^xI`FO$#bsaC6$N+se*0C=9q?(VJwyz08{>nS8|14Ri`NjW|6vFCY~<2X!D
zPamFkFc>6mP)gD7_oY(m!}ay`QwhtOKve=Kfje<4T-PlD7ka&(Ev30R2L}hVS}lCv
zPvH!EdwXcDop!suEQGLPmfQhOj=VQkS`Y-!3Lyfel-$|bq1){e1jk2Zr4&jjJkQhR
za``OqF!0;hvLRqgQm!3vPATO@2u-XUU@#ci#bWU(U|tBZ5Vu~&4UQm$C}^!y*F?z;
zhr>hVBUqL-8@|R8i2FB(&|23`j7gj)2m*ZHkF}0%+d-$(xe<O&ClLrp_Ja+;_I>}*
z>4XqRl1v(G+g8nH^Ox|`5kfdx>ro-&0G<T8Kt4`DrBeA7*vaK`1VM1*w8tr*nwr9K
z9J^MlU5gAy&6Eea5)*=}333A9t=ZXG?Kn=V!YHJa<nwuNdwcuy)z#IJ1rD^<Q3t64
zO^Jzu<s@O1O64=))4931p>5m8Di=afC=>!<cX@gFYGi6W#g~9v67%mnnA$HEN~udy
z${&lxqCYb;lc?Nr92OQ9Jj=2=Yin!oUcY`lnvB|!_eJ1uAQ)xC2QY;~S~?b6TU&4E
z^Z8Y!lpYKQmQqRvL4e~p+On+S)YO#IXf(c9Sy_3nUa$8edmCEon<F{Iq+^({Ah~ko
z%K4?GrPmf07thSk&o5;%nOvvS*>qiZvsSCsFJHcVV{FSVu&Mu5bOv+#jua$duHs9;
z&!Kq|A%rMk!fTpm2AH(liYPAuPXb?s^LJInIp6}Y&M|eN5F&#~<ujNdlf}gMKF|Yh
zX|1DW_z6s@{|%AyJgqF>z~t<SAcPP)IXIMnXMh@GWqDd-avr#e@rj8W$Z=l4BN(s$
zjtLu+5i-CNm>98%30U`n)4*ex!sDJ>vnc+z=5!pR_Ph$rVru&+JWO6`a1ZVIKQ!BC
U#7_5uMF0Q*07*qoM6N<$f-QYjUjP6A

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/radiobutton_normal.png b/components/custom/styles/default/images/radiobutton_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..6ceab7ee66870c38426577bfbf9eeffe58b9474e
GIT binary patch
literal 1752
zcmV;}1}FK6P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ea000ea0W}m4y#N3J8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H1231K!K~z|UwU=LP6WJBUe;(UooOFmChY)8li2*?pZ|ky4lZucS
z&~CQykao9~U}=G<8>#Fo((W4)5(uNJZ>28?L=-9>cxr{TEE3yNs|#w_C2h*)4^aLz
zbqG!dCr(Y4@r3Ea+#wU=ps>3=($QGfnR~wT-81KY*JYX}OEd|n25N8KyjeRkG7=sg
z9j)?uy+&PK-DEr-AB#jH8DI>U0G=&nQO^=$mT8(6@9F7z>)N$z8z&|v8ViL&u23jU
z8iq0Da=F}IueZ|U@l<)eUazXEUvzYI^zYxl|F6Ix@YTx}cfEuGN!Rt)lF8)mD_5?(
zGd(^1k4z>rkWQzE0Ua<LRk{F4mgO>4RX0{uRlT7oO6A_Ydw<{6)%7P}XfZ|>1K>}k
zQk_SR9QjDow0pO1-MWy^=O;xqPk}-S0B$TsWx!WmUA?BRu5NdAb@g;_Z}0CaD=Sl_
z*eC@cc>46|uCr&)zCSWD(mOsrJ_zK2S>d_>Fjvfg1Aq+pf$|L-HoO@QhqoU;e*8Br
zEiIn_Qwy@0rs;J5$&)7!wzjt3P!y#bcpKOZ#DVp|Y9I`(075_|5ERcUU?rdeYk)>z
z6R<TBi5zTeYx}aVuWy%Wn#-IyoypyoE?xS0B9XYMD9SH^w}2L)38)8ZM55(DIZ!65
zw7neo4iFFkRbU<PeV{E8i5%Rzb?bFa)7~~sQ+feFHk;kJef#!-a5#Jr=m4651|TA;
zTP~9N1jU{r_lp0Q2_QiMdJXVBpslg7@z*<d?)-yknlU@CBzD4o?AWpWj~_oCc=+()
zFfb!L4?MwY9((T%<{QxIbHWV~`&9JIe}&Hs4Gn#)X<GHUbLZLxP>X@Pcki|*5{Y41
zmUjc~z<0%dSBYwTqDo0L+{;|T`XanyYbpd2>wq7qs`{&K+qPXZP4jh|0r#m>r#dxF
z`%KsMtf<(o+WzG1jyDD9k|x+R9jqAQ{ikBRC+T#0FrUvqy>Q{eMnIB)mHqwwE#u?k
z*F}(>*d8`7BxeyT0#XXZEHInP<*uGTfBtn~g>>)Uy|wv#zH)MM@;@S|IJvo$<i$XW
z*sww9z*l2qW1o$Vj<x`*)YsS7I6FIg#}VM9d`XqR42uJV-JpeBE|)b7!w*zQ>2!KU
zp-`A&zQgTqe&$%<)iW<-p%{cQH#awP`}XaiG%+y|(sg}`g`d)b#9y=e1$bE4oX-ry
zm>d`w2uVdjrGEcE?D@$kg+d`smgVJG->_}27vK3-&E@fUs$#L2CPgBV30andSOdg%
zd#G5^F4s2&<Q!5GAi3RcrJ<oAD>XMa5BYq)DDyMjy%>;hDY?6%q9Wk&cxHiVDH@Ib
ztGv8?CKL*VvBsyD`LSz*cx4tueDQep0A5v9x2URm9T<~<NAY;PueP?f6>H}Eia<PP
zVW}V-amC4Hz^5om+pb-^ZU7kxm^*Obz#oIbV8Z9~1xkQ$zY2(=<hE3MepIhsy}GHa
ztjyop*?9waCIQsf*I(bXY11c7O-(<;5*B`}<I+9_UjVU~6;*Ecl`YZywY9Y$bai!|
z1-?WC0X#W$=ul4}5O_mX)fm<hTqZ!sl<tdSCQ9zNSi=vL#bU7^2ZKRv-@bi+!4{}a
zNp|t##b30yw+{sZfp@X=+<Gi&6#^8okW&r09d0M|3GfwI7nwRB7L7)`6NyBBCX@M5
zNl9jl(i106eAwFB`uB>8ik}J)4Orr&8cXjv*|Gb@uCg3Ux`nXB>l)y-Xf*o%mMvR`
zuU@_SUa=^3A3l88Nu$x++&nZlHz#E>nGX%a`1j1r%ybd8_S3G~uH2~!Z7@nK7W+v!
z9PUaclgZ7SH-C&J&*t}Sv5U#&%a`9tCX*jcO-+s5xpSvCm&-k3UaUBEp}qe$C>ijD
z!{K$2NaTZHFsS$R^!&D_rsmHq@nT||Ti5m2(W6J-OQllp=5o2uv)OFw{{8y{0)%~X
zJ_q3Oc>HVEu5D2i<xNFVR_@ue=WKU(_osY~tC`c5X_^*4bLLD(DwX<SE|*)c>w3m8
zj7h^VvM!g)<MDU`Znt}dEX(DgQ0SjKcI^0DcXxM+Z+JN^Hv4+64h{~g!^6Wh4<0<I
ul4ZG2Uth1q<MD^9R;_vjq<Mww`Tqc|3GbDPV(Vf60000<MNUMnLSTY+q(jL7

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/slider-background.png b/components/custom/styles/default/images/slider-background.png
new file mode 100644
index 0000000000000000000000000000000000000000..3ba9c4731f7bd4f0aedd487592607d1185ba90b2
GIT binary patch
literal 293
zcmV+=0owkFP)<h;3K|Lk000e1NJLTq003bC000IE1^@s6)A#T}0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy$4Nv%RCwC#lrajzFcgMglG><4#l|A3
zi#>y*U{^tK_X=*FMC#z=1w4QU=<3=#)Iy<Z#>QCRCCro$zU7Vo2ajY~HUoe&x<MH@
zY+=wFy7w4kmtYjE<5+_4_ka-M=J_*S*FoEAR+f*gdaHp)DP1M=1VS+e4B{eKieQWZ
z?)RZ6ilrAtk$S$Gp^T@%Id>5(MbKIU?hZl-Me4df<$1oVsw%`f)J<du{6JqRWs|1q
rm0*<#-VW#j<!&Bpe9$|3{0T4s@?SrIe|=;D00000NkvXXu0mjfXxn&x

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/slider-handle-active.png b/components/custom/styles/default/images/slider-handle-active.png
new file mode 100644
index 0000000000000000000000000000000000000000..83cec3f4b3d4f8674326dd981a2df2252f4f2e6c
GIT binary patch
literal 506
zcmV<W0R{evP)<h;3K|Lk000e1NJLTq000;O000pP1^@s6$9QZo0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzoJmAMRCwCFltD`ZQ4q)H?b}_$ED!_9
zAdn<j3aN{Sy;u-*m%d7fr>uh@o%|wx1L+X#!GqBu7sFGKp#&Y0rPbZH&B$)-)rU6l
zhsVJC{deBX4zyY=z+fl^#Zf9sL+MLO3-9uf#Uk(mUaeO5v)Syuq9`U~Y!@UV2!anG
zgf$+Iuba*08>R%od97AEM)-qinrXu@AeBnV@L@Wgf^FMiS=QHNGP!6p8qZXcn#pAD
z%H?wU2;qSc;5v?!fzCOc6pNtidb-o;++ymA-bzzd_3R*@2jTlvCddZeB?hrL=jX&;
zG#1}{Th}yLRp1u`GB=6+*X=b0`xk??h8i7wY|gq2u=#<5Gn~X}S_#ziJc81!2MYt&
zbst~){ma8bVI>By!yyneGVpu7-c2HrFunPFYcH1rJWGKQ3h$#4^aq1)ViKDsh-k@5
zrDBvyr8>e-aUbo-7~mfIM3bj(w_9(w+cu^g7H&V<h8v;u_%>YTM<x%{4D}Og#$u~l
wjfqJbki3{g1Yz;j9m_3i0AUr8S@0{s0Da(>5XlFVNB{r;07*qoM6N<$g0)=W$N&HU

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/slider-handle.png b/components/custom/styles/default/images/slider-handle.png
new file mode 100644
index 0000000000000000000000000000000000000000..765e610ac3adae3ef202e786aec4d18d5246193b
GIT binary patch
literal 516
zcmV+f0{i`mP)<h;3K|Lk000e1NJLTq000;O000pP1^@s6$9QZo0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzrb$FWRCwC7ls!wsP!xvGO>PpYRVcL<
z`{7ywMR4hmr3!+3@vlhfWOXPMr~Z-tgW@1$=umOWXo&@BDhRcfrup*Rn3SxI&4G70
zkmtSU+?yAAy&hl@6o=wb6eXa<EhPls@&Sv4U?1LWHc#{U{3FM43L)eKVwC53AFk`F
z)9LiK+wJPuav7X&wOUn#KPifmk!2au>2w@EEEWsUG!0Z${W1*Ws?+JbvXN*un|-L)
z>lwLH0mruCXFiW*z!3sx)hdXhm>CQP_t?7e_f09iC>IJ~u2%5hvhjfBVi9<rzx3H`
zMY!`r!f{|b4(zIsxzE@%ylu;}Ab}zqgEfwpl)>Nbl9>QD23CRw_<wjyd_gI^`JF%=
zd@PK~*uH^jn$NnfUzbazofy1NCcv1XfioJ7?j%W49M?TK&gDQ9gjnD;uGyH);B7qq
zW=zIrFGxbA8jXfrtJT_QbdGs+6vqH_=o3%=G8_)u{eEA=){+G2$I@^wkQhzFZL*Ge
zut89(Kx-0-Y8nxVX~1Mh<c1IujqXTqTLTED2+h1-0R{jKft<b!y%dfB0000<MNUMn
GLSTYFmgp`3

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/slider.png b/components/custom/styles/default/images/slider.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f310e37cecab290854b8552bad74b71ef0f9336
GIT binary patch
literal 617
zcmV-v0+#)WP)<h;3K|Lk000e1NJLTq006`Q000aK1^@s6JslFV00004b3#c}2nYxW
zd<bNS00009a7bBm000e&000e&0sSqbNB{r;8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10p>|WK~!jg?byGoQehm&@%MA?xn!=M2I&WcM-K@OLPUj#(^<o{
zr6mX=`Xy#Vw6<Mph;CyvGz89}gAQWR-PEBDN2sO6k|4U4=Xjomqx}O>hWGn|@A$xX
zcs@MO_p6G<A^@)IUIeZHX8?r|n@<C8f!$WC^#VW@i$z@5y`{CjIvR~0b~>H+v)L?M
z9*|&&jg?F$x60*mp-?E?R7yQ+x7$0a(P*5|TEA&Fo7a5b{{jTSf;c^Ty)6szSEywf
zz_xAMN2=B86T>i0o51bqblUWN|1<Cn_)Z)O353{Gt3a5*Vc+)`lgZ?jWm$Jj;QVkn
zd=AWjufRSKB4H4lO#xfL98jL;byKO-brZ;Xp7#m(v8>gXNr+7s5eH-DdESRosdUoR
zTCbjukT?ht@;ZovAtJu>p;9W+T4MlyHk&=V=Ej6rhu>RN$8nBFQS{MJO1;kIas}c6
z!z7-(m6X&0D1-RUZ`-zA4#RNI1a{KtbU%~Hyd00m`^4X+koY+fVpA!WTPDYGj#-v<
zVX;`8Q-G@1>vy9lx;z*R9(23iy&wpFB7ykd$(;9RR3ec$RH;<X=JWY`K@dFa^?LUe
z@#=|Mt#(OkeZw@(Q)_Nih<_#sf_L-z{BghEe+uvm3W%-IX6h|V00000NkvXXu0mjf
DB;ptf

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/spinbox_down.png b/components/custom/styles/default/images/spinbox_down.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6f3f79e969c11f016fd52b2f2db681b44c7b8a0
GIT binary patch
literal 347
zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQY^(zo*^7SP{WbZ0pxQQctjQh
z)pvm~<6qsy9za3K64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1TUc)B=-
zNKCCgZ|is1L4fr^qIs0$|7|;pVj>?gXbK(V%$R7w9RAQkrm1V1QD?bqq|(Z3C*sam
zgoSjj@i2J%d)~Zf%T}%O*L)hp(fHxK;pesA|7AbiTOaDRcY12&cX2nD6|bxOUGz6;
zbTt?AEz68LS|}6qxKPG1d$01M<0ihn3=ABHKb(#FeX&&b?8aigE!V8m>O3YbVPp_^
z9^m!!&bGCVN4WE5rExRN*689(FW1yqS~uh8Nr~b&zvZ@EyPYU;%~4>>=g^tYEzfwV
myVyi!zwgYLoO<*7SO5LjA7%cU@gf2gIt-q!elF{r5}E+RM2Z#w

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/spinbox_up.png b/components/custom/styles/default/images/spinbox_up.png
new file mode 100644
index 0000000000000000000000000000000000000000..a484194125fa292abfbcc444358c00906990da8b
GIT binary patch
literal 341
zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQY^(zo*^7SP{WbZ0pxQQctjQh
z)pvm~<6qsy9za3K64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1SpdAc};
zNK7p~XP9-^K;+oR^P5s_S(}&b;`o%3aY<rV<*N%zpTDr2rC5H#*XkRK;>$a0%RdNg
zn6Q!e=(6C0yf5pk55Irx8XB4ycmKOSLm9)ot=H0HRGzheubZrLa^6gNhME?Eynn2v
zvHDYj-k-_YdhL+q_K89BW-Z&fm#fDx|Jp5UO;v`54yCkx>WeNL@O<Ncu`4gTr}ES$
zotf(e1E0)^X0~V(n8u)RYg?_#qU$#2&pzGHuwaT)pvY<yU;ca5;!{(9N**`lR@}F~
i@&2*GE0;}b|1t=bnOZt9+nombj=|H_&t;ucLK6U%`G(g3

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/spinner.png b/components/custom/styles/default/images/spinner.png
new file mode 100644
index 0000000000000000000000000000000000000000..664c2b1491498ee0158cb7674602265cc5f5c70c
GIT binary patch
literal 2629
zcmV-L3cB@)P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T700001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L0E%e<0E%e=v1PL|00007bV*G`2igM<
z0yrX}$<`hK013rOL_t(o!?l=ua8%V9z<=M}fELP)f;_|2*y%_$Ar5gAt%|I7ZNw_F
z8%aCZkpWthp|sGBv011O+Pce_j5F8{y2T{YN=tWP(+VP)?uFPwwNp*3kEv8Ki%tNw
z#M!OX2g!c@qvyu!5)f3*%+9^%?z!ju?svY|`Gk{bx8Hs{B0_U>GXRZ^jb%V3Fvnb*
zo12?E8yg#~{{DVxZEYP~ym)aGSRf+XRduI`ya2r2+S+=QQ)ne8GpMDd#RCIq0Tuw0
z0aO(cc^v2jL{$p_B65+cR;p?xaEGe?TSRUIo<0>oYq*E;czoEtk>KU3>W4#Bzij%_
z*4Cy=mMj^is^dijKt%)*8LO%vcymS~k&mrW+&>{;aZ^?Q{f~Xm)JSWxxel0NQ$%F4
z`G7(5>~|va9Kg*t-%L84{&W(I$KzHs8YLc&pA(PAe-VqtDp#&t$?Das#ccO(5!qy<
z<1Id=v9WQSr=zM`223^gmid^it*xyJP$(2UsVxhK!<!?K$XV%hnn)yK9TzYbixH2<
ziAJM^SS&Uc*a9pQk^AHExZHjB-Fol6_lg<5(JWe`s;KHjV4`o{3932<D3~=~1pWe0
zTU#42FjYVds0BJAk;vF|I$elFB80=?V*y2kXf#SJ7ArMyvkb(ws`^uaRjXF1kxHkC
zJn6kBB4xl7-&|A8ZNXf3x3;z(Sh#RuV9S;*gW+&^6!4(=2vybDKspkMj7z7}baZqa
z3mA<?z1v4bWVWiRh<FS9Bp#372(W0;B57%9ISRNwiJjqXscBy|pd})rz*c|_8#WA@
z=WA5;Yrvq0s4=vwf%`vE2SwyXV|ijEFkmKlI3ABrYj1D&EG7+PRrL*3-3Gh@aO<tN
zTB^De=m6eS)!l7vZQFg;x&-*XXW@WljOhhcZ9guc=Srf{=$$|f@T&2XB?fo`@L((!
zvy97mNkkTj$i*!!EjKndH}6@oVuhS}=9z`Iwzl85wY5c5wNgZud258j;TgbMqb3EP
zA8rG#>ged`GUGlHSh2tJwmKe<Pf^tefLimlUi(=z8og^cm#}>Ka@MY0dt8?h4u}6F
zA|am-{Qy{&PNyF>(v>4ej%a6R=kS04>({U6@ZrOOrlzJrW8HTFtIamQ2`pH-a^+4F
z0xc2I=H_M{4ruY>#iFWsY7q{HLn5*fm;n3(s86TUe*>61cdqr=V~-V%QMp7SQ36a;
z)%P138uodAtXsFPWa-kS0|s)AfozIKqdSYG{Yfnni3~Yr133>^nNFwk0M}oCy=>pU
zT>*l@;Ar3qRUHtKE=eR3WvcotV2Q}1s``Y8?5VG>|F3_MHEY(;)YMe0uO|%%oG^L>
zgTae{SwO9-UM(W~RP}O6BoZ~My2Gbu1z?Y={u$_KXlQuWKT#|e8}gZ_(uRW!27~7S
zVO6~jxI#oG`opV;%#uVRvBtz#H7;d@7kfqIT~*yBB0s9HuYYyjx^=R2=~Cr0wAr&~
zOIKHy27|#WpdG080Sy?t2$=poCBR$*BftnV&ru)%d=a=5=m!V{0-p)atm8$aSAesM
zJVZ%Raxy~_iNt-XS_MoHkx5=EWvmt;-O$ib%V}uAU~r?VE--8LiO3<~0B{g^Lsff9
z>g((8NF)*gV4|u{7LhU&{L6t0MPw_dul*8u(!d>1)k9rfT?aoV(uW>;$f~ceA2j3#
zfFYwuBoZS}2i44(GqEho+O=!fQ@~Th=xM+UwUSDuL{%-LhB|-#{K4WEHg4P~fZlS;
zEuSlBWo6|U5g8>Sx#ypM{{3Nfw)jCZnY2V?lF3fWRQ2_`y1Hjiha{`2s(uK3S5^OI
z{NC##vL85P5{<V?QmNETRh<T$2TV1&-9!U80r(>@?=<P)m8yCHaDiu-#)=OEZ;42c
z1>7kj8${$D5%~@<M^&p093paYGMO9?kV>WGbC4PU)2B}_Rn<#<9%DdNj~ahGPDCyM
zDlFi&qB#acq~P;KM}Z3O)b?2cD=I1kz_P3nz;8w5H50u`L}Y|H=M0+lcStIgssVO*
zM@V0L8h9MoGJpR3e|isH_y38s<2a`Tme1z_ux-0oqF+$edBE3!tAX=;TYa6RQmHcF
z@4kb0mx#0*up`4Q=DIGbN+=XMDY#rNhlmWp<#M^ROG``N8D{&x0ywH#XO68k7~Ogx
zl}hbPCX+WMlgTr@7dCC$6!1YsGnvdaUO$t`oU-%`-0XZlpUvm<P5#Wjrl!X7fsUCz
zeR^3{RaL+P9O(xG*s)`W7_bSMOy)P4Ohz-A%$u1^Cg_cM=9y=tr>Ez*VA*U|ve~TV
zgS#e|%N@$)a%z5m$mjFp0s8y<*}Qr4F*+{EWRkkNx}gW#wr%5v8*cEVbcxyS3SY+Y
z5>V|p&WFQ6?cKYVY15`1Pm)npjrm;)uoq~sZM(~i5wBul+xAC?rmn6oGMUT}oa?%`
ziHNJJ6-8x`77wnwySuEXr{}Dq|HUW4@!4#4w%509J8t6dQ0YWfr>SaZKA(@~^LcFB
z))Ph&*L9}?KL-~2YAXRV+xk!_belJ}r>CdgB%6N)c8bU&GiJ;<(%aixVf^b=z=yz`
z^78VRjf6(3>UI%vRCUm#U*74i6PRb)_WLI)9(_+$7y7bm?~9%SmV1M`ySu-ns&jxz
zKtx2osjA*W6HI>!P_C-q2H3xUe~E3|ABso=&}Tk8;Hy9k_~C{HRMq=|-M)Sa@D5NP
z3WeV5?(QxzIur&b`h3>Q)z#HG^ID&(zT(rf`MtfpW#^uI?m&Nkzh&F@tH2LT1QAnU
z>H@yyS-ofZmfvl-u1hEsdK<XO_(Sji6^`S);JU6=U0v;!*sd{PM-A{kU)JoUZkTO6
zUqtEv#*Q6ZF#4EQ)n@a`9ucXvZTsDPK98yn`OG1}P$-1sIJmBBg+ifzV6Lie1==0Q
z`8B}k(WBLD?<J~wm4UGg$N_-f-d?M`y!>6@pcgJp1+1aBw|5*sUtgd1A!~qDA`-D}
zyFZ`LTefXeT3UMi60qYq1=n?P9Opm4T-SBQlkjDiUFPZIwIXu1iPIy1_e7-6r#1!P
z4YP#-b3I=~YJp#sm6egp<*;qL-<06Ie&M7mtX`yW97kQ(W#q__p5;ywkp)I70VAb@
zs(Q$OC<3xYXB&X~vf1odfH7mneEJ%-<2c2M1G8q$^0sRfFvi<nQy+ZGB$@cE{x#q|
zAKU@pQBP+r>*GuNxAml|{QhjED06uoxKcze1cJaffaj{KtNT6A>yzLUB63hww~EM%
n<>lplMo$qD%FD|?QG)*i-|6WSYzBoC00000NkvXXu0mjf?5^_a

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/switch_normal.png b/components/custom/styles/default/images/switch_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac46b2112d5cb7a7bf8a476bff4f14c2094f253d
GIT binary patch
literal 834
zcmV-I1HJr-P)<h;3K|Lk000e1NJLTq003?P000{Z1^@s6owT}%00004b3#c}2nYxW
zd<bNS00009a7bBm000e&000e&0sSqbNB{r;8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10>4Q_K~!jg?b<O&8&Mbs@c;MTUG83!$R*I)C7YvIvN*IT(!ov1
zU>A!;aO~#b<m%9=qf<dj#lgivTBw7IgHxb$DH$vliLLcwn%pJ#z7FxwL<^m~6W(tM
z@0Jff{_lHtc~mZ!G06A*M?{pl@xZuqLWp)Yn>`&|x8fi5dR@7$yC|ic8Xg|Dl~Uci
zEz!755CoZviwhkD!KY5A^FE)?2f$_H>h-!(O1+(%n{!uIRvvnu*8vbFTCowcPft(X
z_4W0a`}_OPecykjweDB|;JWVO%*;$?ZEdZ@%wM$DjijqJt`v*K?CR?3m=K~=tyY(7
zwb~mhm&<52n;#Aj4<CD;_l=o<C0(d-tD&Q#qbJMD%T%k?o>^ySXI`;bbUn|@MN#wz
zfH{<;Q@d0uNg;&iIF7QUlo{K$0f2}|0+0z8X#4{a!EqchK0fYP@d7hTt+h#8iV=|{
zA^}``9RMJi*-oe?<Nx$Gj)(}oEz%?|-J}qruW?{zp|v)NOEG4a0Q$B{VrI$ACUGgo
z%>9W2Kmdf9aj7Q&h%gMP?^J0Tmu}1~iAW3$4fQ3?Y?bLJFAtI!Oq^+4id`m70%peD
zH{xH3GmT5Jc*X%RGwz;|7(7*?choeAOR-zu<IG3q^ozfo<nwu0Q51z*Ys<{IdqH-)
zU7?hUtU{siyWMVw=jZ3baU2yzQIvFb#!XU6d2(_hlv3U8?d@|50GiF_=bfFMsfC4w
z2SE^oQ55N<3pK6?Aw(vVv3GZOX=G&N>%qZ6Z^pG+t#^BSdoPISX{Az8xm*s+%t;q)
z^!{@5eIHv}TXcMU%u7p4uQxU}K=FmxMx)`(&dzSMTCIw0+wpY<BVl3KyCpd~I{I^R
za&mEge*PnXtH#Bu)hcanZjJ>(kh}XbjX{M%A)J_)_&z;7{p0%jU;0!ao{N=pyZ`_I
M07*qoM6N<$g4~^fu>b%7

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/images/switch_pressed.png b/components/custom/styles/default/images/switch_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..a04a3f4b0f52626f1145359b45cb6c3f850ee9f6
GIT binary patch
literal 709
zcmV;$0y_PPP)<h;3K|Lk000e1NJLTq003?P000{Z1^@s6owT}%00004b3#c}2nYxW
zd<bNS00009a7bBm000e&000e&0sSqbNB{r;8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10zyedK~!jg?b<PG+dvow;8&-!&N?Bm3nf{#mV_ow4R&b>HLd9o
zFovWWIutKm{A1c5P;k3=D|F4~!63XiV<1D94kZvOkR!>JBCbR0)Ja<k9b&0`&m`_Z
zeDHF2pU`RB+uOKqHk;iBAby!3H;yqjw=C=I`Z!-a_`Y8*l}axR!+7F2PNiHfYd2dW
z`JFUP^&kk+FbqG0Vfe<j?XSR(;C$aN3n5+~930%++uPd_LO|0fx4ej=2;=eik>`2t
z$;ruM!!QyK0G#t)x7)q5zrVjDrG&2QtFDzSu`CPic3WqRJ*-x%ua1t6`WyflWA{6q
zPE$$=&iUWoLvEO^>#!^fjYb2<$H&hA^jQ=|cC}iq2q8FymS2nT0NmQz+Ol~Z$9!#V
zP1iJy&b6FljG<I2vCYj*`^pld;EIE-x&ZQTXvGy22fhbJXI%a*XGB|NLD5!OP!wE&
zEayX8WkFr8IBHIcftr(oqcg6cD7XTl@3{W}H75mRnkKkunioo`%U|9UUVbU1kYyR9
zlo^v!&gS!Zlq3m~Bw2NB<PXv`#rgR;Ow+t@UH5EpS?JL7yr->JtIQaKVHm5flPt-y
z3_%cJGMT_}oR76yE#m-?rs><!X!M*h_Ml#`LrMw8sBg&wr4+(2gy(rUJv~LQ*Xs`k
z189p2u|f#5*=)Xx<G3S)FzEhCJ|sy3r4%+cHoml4t(UIrz6bC#xP|F-stt$3yT0#N
rR#GXsVtsu*+TGp#)NZ#wFOPo%NynoQ#A)9A00000NkvXXu0mjf`6)a4

literal 0
HcmV?d00001

diff --git a/components/custom/styles/default/tools/ColorConverter.qml b/components/custom/styles/default/tools/ColorConverter.qml
new file mode 100644
index 000000000..5070ff1eb
--- /dev/null
+++ b/components/custom/styles/default/tools/ColorConverter.qml
@@ -0,0 +1,59 @@
+import QtQuick 1.0
+
+// This helper element allows extracting color values
+QtObject {
+    property color color;
+
+    function intValue(dec)
+    {
+        var result;
+        switch (dec) {
+        case 'a':
+                result = 10;
+            break;
+        case 'b':
+                result = 11
+            break;
+        case 'c':
+                result = 12;
+            break;
+        case 'd':
+                result = 13;
+            break;
+        case 'e':
+                result = 14
+        case 'f':
+                result = 15
+            break;
+        default:
+                result = dec
+            break;
+        }
+        return Number(result);
+    }
+
+    function convertSubstring(val) {
+        return 16*intValue(val[0]) + intValue(val[1])
+    }
+
+    function grayValue() {
+        return (red + green + blue)/3
+    }
+
+    onColorChanged: {
+        var string = "" + color
+        var redString = string.substring(1, 3)
+        var greenString = string.substring(3,5)
+        var blueString = string.substring(5,7)
+        var alphaString = string.substring(7,9)
+        red = convertSubstring(string.substring(1, 3))
+        green = convertSubstring(string.substring(3,5))
+        blue = convertSubstring(string.substring(5,7))
+        alpha = convertSubstring(string.substring(7,9))
+    }
+
+    property int red
+    property int green
+    property int blue
+    property int alpha
+}
diff --git a/components/custom/visuals/AdjoiningCorner.qml b/components/custom/visuals/AdjoiningCorner.qml
new file mode 100644
index 000000000..92027cef4
--- /dev/null
+++ b/components/custom/visuals/AdjoiningCorner.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+
+Item {
+    property string corner: ""    // Can we use Qt::Corner? see http://doc.trolltech.com/4.7/qt.html#Corner-enum
+    property alias styledItem: loader.styledItem
+    property alias adjoining: loader.adjoining
+
+    clip: true
+
+    anchors {
+        left: corner == "TopLeftCorner" || corner == "BottomLeftCorner" ? parent.left : parent.horizontalCenter
+        right: corner == "TopLeftCorner" || corner == "BottomLeftCorner" ? parent.horizontalCenter : parent.right
+        top: corner == "TopLeftCorner" || corner == "TopRightCorner" ? parent.top : parent.verticalCenter
+        bottom: corner == "TopLeftCorner" || corner == "TopRightCorner" ? parent.verticalCenter : parent.bottom
+    }
+
+    Item {
+        width: parent.width*2
+        height: parent.height*2
+        x: corner == "TopLeftCorner" || corner == "BottomLeftCorner" ? 0 : -parent.width
+        y: corner == "TopLeftCorner" || corner == "TopRightCorner" ? 0 : -parent.height
+
+        Loader {
+            id: loader
+            anchors.fill: parent
+            property Item styledItem:loader.styledItem
+            property int adjoining: 0x0
+            sourceComponent: styling
+        }
+    }
+}
diff --git a/components/custom/visuals/AdjoiningVisual.qml b/components/custom/visuals/AdjoiningVisual.qml
new file mode 100644
index 000000000..09bc34cc9
--- /dev/null
+++ b/components/custom/visuals/AdjoiningVisual.qml
@@ -0,0 +1,50 @@
+import QtQuick 1.0
+
+Item {
+    id: adjoiningVisual
+    property int adjoins: 0    // use enum Qt::DockWidgetArea? see http://doc.trolltech.com/4.7/qt.html#DockWidgetArea-enum
+    property Item styledItem
+    property Component styling
+
+//    Qt::LeftDockWidgetArea	0x1
+//    Qt::RightDockWidgetArea	0x2
+//    Qt::TopDockWidgetArea	0x4
+//    Qt::BottomDockWidgetArea	0x8
+
+    Item {
+        anchors.fill: parent
+
+        AdjoiningCorner { corner: "TopLeftCorner"; adjoining: topLeftAdjoining(); styledItem: adjoiningVisual.styledItem }
+        AdjoiningCorner { corner: "TopRightCorner"; adjoining: topRightAdjoining(); styledItem: adjoiningVisual.styledItem }
+        AdjoiningCorner { corner: "BottomLeftCorner"; adjoining: bottomLeftAdjoining(); styledItem: adjoiningVisual.styledItem }
+        AdjoiningCorner { corner: "BottomRightCorner"; adjoining: bottomRightAdjoining(); styledItem: adjoiningVisual.styledItem }
+    }
+
+    function topLeftAdjoining() {
+        var adjoining = 0;
+        if(adjoins&0x01) adjoining |= Qt.Horizontal;
+        if(adjoins&0x04) adjoining |= Qt.Vertical;
+        return adjoining;
+    }
+
+    function topRightAdjoining() {
+        var adjoining = 0;
+        if(adjoins&0x02) adjoining |= Qt.Horizontal;
+        if(adjoins&0x04) adjoining |= Qt.Vertical;
+        return adjoining;
+    }
+
+    function bottomLeftAdjoining() {
+        var adjoining = 0;
+        if(adjoins&0x01) adjoining |= Qt.Horizontal;
+        if(adjoins&0x08) adjoining |= Qt.Vertical;
+        return adjoining;
+    }
+
+    function bottomRightAdjoining() {
+        var adjoining = 0;
+        if(adjoins&0x02) adjoining |= Qt.Horizontal;
+        if(adjoins&0x08) adjoining |= Qt.Vertical;
+        return adjoining;
+    }
+}
diff --git a/components/images/folder_new.png b/components/images/folder_new.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d8bb9bd768d8e8ab785d95483ead02ae6800dc5
GIT binary patch
literal 1199
zcmV;g1W@~lP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101k9TSaeirbZlh+MsI9nWpZ;NRH|S>0000NbVXQnL3MO!Z*l-k
zVQ_CCLt$)TZDDR?a%E}Xks2xh001d;MObu1WpiV4X>fFDZ*BlWVRL0<Aa7<MN?~ht
zVjxp=Wod3@av)@7b7^O8po9f;000BJNkl<ZNQteLO^6&t6vuznRnt8)&TMwwuc%3g
z2L+Xg#E;-dLX;fTm|zS9BAz685^_-q9uyG|f}n_a(2IhCBC^TJQ#K*NgBpV$m_(v6
zF_>g`c6MfW=cA{)s-B0L%+9*2hHM@b)l|QFzxV#Hs#}Q&%d^*l_WY_}>aDt3Kzece
zdac!cscYUPuC`9W*HJk92_px7S~kFycI-lAJK{H5*Ic8E&yrT&@tI8VfYQZJ^~l(l
zmwip|#uxVO*{fCXra&~m+D)M1J<q-M(o_YJ-N2KO!4!9)i@N~{((3y=LS69o(vGrO
zId*svK%9I1q0Ns(S_gRVJHz3<CyrYKCr=*#c)D6YRLJYc6$)i;#1wY6Gc7ztQu%<|
z%y&DLl1=G}{I<c{8{aGdSnG2joc`^XMY0r&{j9rVbuJV9ywwc6OOU;Hp@YhjUvn5_
zmSlGSu)Fa5e&B{+0l-;iW~wBuWYH*3O%mybvOb5M`wVbPbq9Q%v^M5~Aos%}iJWyz
zPnT&lnhUmh??_V18P(#pwbv7wBlyxQWQX7A(KiM^NB!bn;@KZtgZ+2Eya-^er8GH7
zlC*j|g9-v3-n@mitA`mX97b^#d=1<bC_pSCF-RR`hQG?I@|iw=uCEvH;=Vmk_YbTv
z^=7?SSd7u!zu^H^j*c=>Dx=aIqXmef0C9hk*2YO{UlA4_C6ix|QhDZT75Y{knO;zV
zv+nIDwr*o+Xk<RT0tAvIrcx~-;+dSeiBNA~Me-5N@`spkluS5CYx+HE6D1(W!Ed+l
z;A8C=T|gYSMuNaIIeC7G=JoW+8O}}J!${vsiuq|GV&Vj1n`bT_pe1)QG4*-ZzYDO|
z5=A+jv;PSIur9}i$}L25F=3`HX`JRsZH}R#eyp88Ve^30k;@fGlK6iC-D=3tOpEiu
z3}|hzc0S22AnjCOOy-IKOPPqrrb_^9>IedjUM9eK|1T0*i-^A_6{Jg5fY7Kn>iICt
z0`2?LKBu5iorT^=AeX<i(tZ*V>h&5TG%mXZ?KsMa$kgwrf2GxI;;lnGC<)NYV01`m
za%95-+3-3-lf~!|tqgdDcY;eT&3cV<f1E+Ql$25iz$m2@5LK(QhsMXppV_!^MhC$^
z)4eit&U5tW_pVy49t0w#lrtSQ^zq{-zHrWOI)DDs%~ut@W6fss?6G5~#sE!6WCeu4
zAaHAEUXE3OQ$QI=l!%~|3TQVxL#HpxFb|}F6%pV4>34c@%}hFh{|2rA&Q3Ns=Tray
N002ovPDHLkV1nxxBC7xZ

literal 0
HcmV?d00001

diff --git a/components/plugin/qmldir b/components/plugin/qmldir
new file mode 100644
index 000000000..e8452efd6
--- /dev/null
+++ b/components/plugin/qmldir
@@ -0,0 +1 @@
+plugin styleplugin
diff --git a/components/src.pro b/components/src.pro
new file mode 100644
index 000000000..83e0a3d4c
--- /dev/null
+++ b/components/src.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = styleitem
diff --git a/components/styleitem/qstyleitem.cpp b/components/styleitem/qstyleitem.cpp
new file mode 100644
index 000000000..90fa5a367
--- /dev/null
+++ b/components/styleitem/qstyleitem.cpp
@@ -0,0 +1,547 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTgall
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstyleitem.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+#include <QtGui/QApplication>
+#include <QtGui/QMainWindow>
+#include <QtGui/QGroupBox>
+#include <QtGui/QToolBar>
+#include <QtGui/QMenu>
+
+
+QStyleItem::QStyleItem(QObject*parent)
+    : QObject(parent),
+    m_sunken(false),
+    m_raised(false),
+    m_active(true),
+    m_enabled(true),
+    m_selected(false),
+    m_focus(false),
+    m_on(false),
+    m_horizontal(true),
+    m_minimum(0),
+    m_maximum(100),
+    m_value(0)
+{
+}
+
+void QStyleItem::initStyleOption(QStyleOption *opt) const
+{
+    if (m_enabled)
+        opt->state |= QStyle::State_Enabled;
+    if (m_active)
+        opt->state |= QStyle::State_Active;
+    if (m_sunken)
+        opt->state |= QStyle::State_Sunken;
+    if (m_raised)
+        opt->state |= QStyle::State_Raised;
+    if (m_selected)
+        opt->state |= QStyle::State_Selected;
+    if (m_focus)
+        opt->state |= QStyle::State_HasFocus;
+    if (m_on)
+        opt->state |= QStyle::State_On;
+    if (m_hover)
+        opt->state |= QStyle::State_MouseOver;
+    if (m_horizontal)
+        opt->state |= QStyle::State_Horizontal;
+}
+
+QString QStyleBackground::hitTest(int px, int py) const
+{
+    QStyle::SubControl subcontrol = QStyle::SC_All;
+    QStyle::ComplexControl control = QStyle::CC_CustomBase;
+    QString type = m_style->elementType();
+    if (type == QLatin1String("spinbox")) {
+        control = QStyle::CC_SpinBox;
+        QStyleOptionSpinBox opt;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.frame = true;
+        m_style->initStyleOption(&opt);
+        subcontrol = qApp->style()->hitTestComplexControl(control, &opt, QPoint(px,py), 0);
+        if (subcontrol == QStyle::SC_SpinBoxUp)
+            return "up";
+        else if (subcontrol == QStyle::SC_SpinBoxDown)
+            return "down";
+
+    } else if (type == QLatin1String("slider")) {
+        control = QStyle::CC_Slider;
+        QStyleOptionSlider opt;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.minimum = m_style->minimum();
+        opt.maximum = m_style->maximum();
+        opt.sliderPosition = m_style->value();
+        m_style->initStyleOption(&opt);
+        subcontrol = qApp->style()->hitTestComplexControl(control, &opt, QPoint(px,py), 0);
+        if (subcontrol == QStyle::SC_SliderHandle)
+            return "handle";
+    } else if (type == QLatin1String("scrollbar")) {
+        control = QStyle::CC_ScrollBar;
+        QStyleOptionSlider opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        opt.minimum = m_style->minimum();
+        opt.maximum = m_style->maximum();
+        opt.pageStep = 200;
+        opt.orientation = m_style->horizontal() ? Qt::Horizontal : Qt::Vertical;
+        opt.sliderPosition = m_style->value();
+        subcontrol = qApp->style()->hitTestComplexControl(control, &opt, QPoint(px,py), 0);
+
+        if (subcontrol == QStyle::SC_ScrollBarSlider)
+            return "handle";
+        if (subcontrol == QStyle::SC_ScrollBarSubLine || subcontrol == QStyle::SC_ScrollBarSubPage)
+            return "up";
+        if (subcontrol == QStyle::SC_ScrollBarAddLine || subcontrol == QStyle::SC_ScrollBarAddPage)
+            return "down";
+    }
+    return "none";
+}
+
+QSize QStyleItem::sizeFromContents(int width, int height) const
+{
+    QString metric = m_type;
+    if (metric == QLatin1String("checkbox")) {
+        QStyleOptionButton opt;
+        initStyleOption(&opt);
+        opt.text = text();
+        return qApp->style()->sizeFromContents(QStyle::CT_CheckBox, &opt, QSize(width,height), &m_dummywidget);
+    } else if (metric == QLatin1String("button")) {
+        QStyleOptionButton opt;
+        initStyleOption(&opt);
+        opt.text = text();
+        return qApp->style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(width,height), &m_dummywidget);
+    } else if (metric == QLatin1String("tab")) {
+        QStyleOptionTabV3 opt;
+        initStyleOption(&opt);
+        opt.text = text();
+        return qApp->style()->sizeFromContents(QStyle::CT_TabBarTab, &opt, QSize(width,height), &m_dummywidget);
+    } else if (metric == QLatin1String("combobox")) {
+        QStyleOptionComboBox opt;
+        initStyleOption(&opt);
+        return qApp->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, QSize(width,height), &m_dummywidget);
+    } else if (metric == QLatin1String("spinbox")) {
+
+        QStyleOptionSpinBox opt;
+        initStyleOption(&opt);
+        return qApp->style()->sizeFromContents(QStyle::CT_SpinBox, &opt, QSize(width,height), &m_dummywidget);
+    } else if (metric == QLatin1String("edit")) {
+        QStyleOptionFrameV3 opt;
+        initStyleOption(&opt);
+        return qApp->style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(width,height), &m_dummywidget);
+    }
+    return QSize();
+}
+
+int QStyleItem::pixelMetric(const QString &metric) const
+{
+    if (metric == "scrollbarExtent")
+        return qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
+    else if (metric == "defaultframewidth")
+        return qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+    else if (metric == "taboverlap")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarTabOverlap);
+    else if (metric == "tabbaseoverlap")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap);
+    else if (metric == "tabbaseheight")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseHeight);
+    else if (metric == "tabvshift")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarTabShiftVertical);
+    else if (metric == "menuhmargin")
+        return qApp->style()->pixelMetric(QStyle::PM_MenuHMargin);
+    else if (metric == "menuvmargin")
+        return qApp->style()->pixelMetric(QStyle::PM_MenuVMargin);
+    else if (metric == "menupanelwidth")
+        return qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth);
+    return 0;
+}
+
+QVariant QStyleItem::styleHint(const QString &metric) const
+{
+    if (metric == "focuswidget")
+        return qApp->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget);
+    if (metric == "tabbaralignment") {
+        int result = qApp->style()->styleHint(QStyle::SH_TabBar_Alignment);
+        if (result == Qt::AlignCenter)
+            return "center";
+        return "left";
+    }
+    if (metric == "framearoundcontents")
+        return qApp->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents);
+    return 0;
+}
+
+
+QRect QStyleBackground::subControlRect(const QString &subcontrolString) const
+{
+    QStyle::SubControl subcontrol = QStyle::SC_None;
+    QString m_type = m_style->elementType();
+    if (m_type == QLatin1String("spinbox")) {
+        QStyle::ComplexControl control = QStyle::CC_SpinBox;
+        QStyleOptionSpinBox opt;
+        m_style->initStyleOption(&opt);
+        opt.rect = QRect(0, 0, width(), height());
+        opt.frame = true;
+        if (subcontrolString == QLatin1String("down"))
+            subcontrol = QStyle::SC_SpinBoxDown;
+        else if (subcontrolString == QLatin1String("up"))
+            subcontrol = QStyle::SC_SpinBoxUp;
+        else if (subcontrolString == QLatin1String("edit")){
+            subcontrol = QStyle::SC_SpinBoxEditField;
+        }
+        return qApp->style()->subControlRect(control, &opt, subcontrol, 0);
+    } else if (m_type == QLatin1String("slider")) {
+        QStyle::ComplexControl control = QStyle::CC_Slider;
+        QStyleOptionSlider opt;
+        m_style->initStyleOption(&opt);
+        opt.rect = QRect(0, 0, width(), height());
+        opt.minimum = m_style->minimum();
+        opt.maximum = m_style->maximum();
+        opt.sliderPosition = m_style->value();
+        if (subcontrolString == QLatin1String("handle"))
+            subcontrol = QStyle::SC_SliderHandle;
+        else if (subcontrolString == QLatin1String("groove"))
+            subcontrol = QStyle::SC_SliderGroove;
+        return qApp->style()->subControlRect(control, &opt, subcontrol, 0);
+    } else if (m_type == QLatin1String("scrollbar")) {
+        QStyle::ComplexControl control = QStyle::CC_ScrollBar;
+        QStyleOptionSlider opt;
+        m_style->initStyleOption(&opt);
+        opt.rect = QRect(0, 0, width(), height());
+        opt.minimum = m_style->minimum();
+        opt.maximum = m_style->maximum();
+        opt.pageStep = m_style->horizontal() ? width() : height();
+        opt.orientation = m_style->horizontal() ? Qt::Horizontal : Qt::Vertical;
+        opt.sliderPosition = m_style->value();
+        if (subcontrolString == QLatin1String("slider"))
+            subcontrol = QStyle::SC_ScrollBarSlider;
+        if (subcontrolString == QLatin1String("groove"))
+            subcontrol = QStyle::SC_ScrollBarGroove;
+        else if (subcontrolString == QLatin1String("handle"))
+            subcontrol = QStyle::SC_ScrollBarSlider;
+        else if (subcontrolString == QLatin1String("add"))
+            subcontrol = QStyle::SC_ScrollBarAddPage;
+        else if (subcontrolString == QLatin1String("sub"))
+            subcontrol = QStyle::SC_ScrollBarSubPage;
+        return qApp->style()->subControlRect(control, &opt, subcontrol, 0);
+    }
+    return QRect();
+}
+
+QStyleBackground::QStyleBackground(QDeclarativeItem *parent)
+    : QDeclarativeItem(parent),
+      m_menu(0),
+      m_style(0)
+{
+    setFlag(QGraphicsItem::ItemHasNoContents, false);
+    setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+    setSmooth(true);
+
+    m_menu = new QMenu();
+    m_menu->ensurePolished();
+}
+
+void QStyleBackground::setStyle(QStyleItem *style)
+{   
+    if (m_style != style) {
+        m_style = style;
+        //connect(&m_dummywidget, SIGNAL(updateRequest()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(onChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(selectedChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(activeChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(textChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(activeChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(raisedChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(sunkenChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(hoverChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(maximumChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(minimumChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(valueChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(enabledChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(horizontalChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(focusChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
+        connect(m_style, SIGNAL(elementTypeChanged()), this, SLOT(updateItem()));
+        emit styleChanged();
+    }
+}
+
+
+void QStyleBackground::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+    QString type = m_style->elementType();
+    if (type == QLatin1String("button")) {
+        QStyle::ControlElement control = QStyle::CE_PushButton;
+        QStyleOptionButton opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+
+        // Dirty hack to fix button label positioning on mac
+        if (qApp->style()->metaObject()->className() == QLatin1String("QMacStyle"))
+            opt.rect.translate(0,2);
+
+        qApp->style()->drawControl(control, &opt, painter, &m_dummywidget);
+    }
+    else if (type == QLatin1String("toolbutton")) {
+        QStyle::ComplexControl control = QStyle::CC_ToolButton;
+        QStyleOptionToolButton opt;
+        m_style->initStyleOption(&opt);
+        opt.subControls = QStyle::SC_ToolButton;
+        opt.rect = QRect(0, 0, width(), height());
+        QToolBar bar;
+        QWidget dummy(&bar);
+        if (opt.state & QStyle::State_Raised || opt.state & QStyle::State_On)
+            qApp->style()->drawComplexControl(control, &opt, painter, &dummy);
+    }
+    else if (type == QLatin1String("tab")) {
+        QStyle::ControlElement control = QStyle::CE_TabBarTabShape;
+        QStyleOptionTabV3 opt;
+        m_style->initStyleOption(&opt);
+        int overlap = qApp->style()->pixelMetric(QStyle::PM_TabBarTabOverlap);
+        opt.rect = QRect(overlap, 0, width()-2*overlap, height());
+        if (m_style->text() == "South")
+            opt.shape = QTabBar::RoundedSouth;
+        if (m_style->activeControl() == QLatin1String("beginning"))
+            opt.position = QStyleOptionTabV3::Beginning;
+        else if (m_style->activeControl() == QLatin1String("end"))
+            opt.position = QStyleOptionTabV3::End;
+        else if (m_style->activeControl() == QLatin1String("only"))
+            opt.position = QStyleOptionTabV3::OnlyOneTab;
+        else
+            opt.position = QStyleOptionTabV3::Middle;
+        qApp->style()->drawControl(control, &opt, painter, &m_dummywidget);
+    }
+    else if (type == QLatin1String("menu")) {
+        QStyleOptionMenuItem opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        QStyleHintReturnMask val;
+        qApp->style()->styleHint(QStyle::SH_Menu_Mask, &opt, &m_dummywidget, &val);
+        painter->save();
+        painter->setClipRegion(val.region);
+        m_menu->setContextMenuPolicy(Qt::CustomContextMenu);
+        m_menu->ensurePolished();
+        opt.palette = m_menu->palette();
+        painter->fillRect(opt.rect, opt.palette.window());
+        painter->restore();
+        qApp->style()->drawPrimitive(QStyle::PE_PanelMenu, &opt, painter, m_menu);
+        QStyleOptionFrame frame;
+        m_style->initStyleOption(&frame);
+        frame.lineWidth = qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth);
+        frame.midLineWidth = 0;
+        frame.rect = opt.rect;
+        qApp->style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, painter, m_menu);
+        //       qApp->style()->drawControl(QStyle::CE_MenuVMargin, &opt, painter, m_menu);
+    }
+    else if (type == QLatin1String("frame")) {
+        QStyle::PrimitiveElement control = QStyle::PE_Frame;
+        QStyleOptionFrameV3 opt;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.frameShape = QFrame::StyledPanel;
+        opt.lineWidth = 1;
+        m_style->initStyleOption(&opt);
+        qApp->style()->drawPrimitive(control, &opt, painter, 0);
+    }
+    else if (type == QLatin1String("focusframe")) {
+        QStyle::ControlElement control = QStyle::CE_FocusFrame;
+        QStyleOption opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        qApp->style()->drawControl(control, &opt, painter, &m_dummywidget);
+    }
+    else if (type == QLatin1String("tabframe")) {
+        QStyle::PrimitiveElement control = QStyle::PE_FrameTabWidget;
+        if (m_style->minimum()) {
+            QStyleOptionTabWidgetFrameV2 opt;
+            m_style->initStyleOption(&opt);
+            if (m_style->text() == "South")
+                opt.shape = QTabBar::RoundedSouth;
+            opt.selectedTabRect = QRect(m_style->value(), 0, m_style->minimum(), height());
+            opt.rect = QRect(0, 0, width(), height());
+            qApp->style()->drawPrimitive(control, &opt, painter, 0);
+        } else {
+            QStyleOptionTabWidgetFrame opt;
+            m_style->initStyleOption(&opt);
+            opt.rect = QRect(0, 0, width(), height());
+            qApp->style()->drawPrimitive(control, &opt, painter, 0);
+        }
+    }
+    else if (type == QLatin1String("menuitem")) {
+        QStyle::ControlElement control = QStyle::CE_MenuItem;
+        QStyleOptionMenuItem opt;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.text = m_style->text();
+        m_style->initStyleOption(&opt);
+        opt.palette = m_menu->palette();
+        qApp->style()->drawControl(control, &opt, painter, m_menu);
+    }
+    else if (type == QLatin1String("checkbox")) {
+        QStyle::ControlElement control = QStyle::CE_CheckBox;
+        QStyleOptionButton opt;
+        m_style->initStyleOption(&opt);
+        if (!(opt.state & QStyle::State_On))
+            opt.state |= QStyle::State_Off;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.text = m_style->text();
+        qApp->style()->drawControl(control, &opt, painter, 0);
+    }
+    else if (type == QLatin1String("radiobutton")) {
+        QStyle::ControlElement control = QStyle::CE_RadioButton;
+        QStyleOptionButton opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        opt.text = m_style->text();
+        qApp->style()->drawControl(control, &opt, painter, 0);
+    }
+    else if (type == QLatin1String("edit")) {
+        QStyle::PrimitiveElement control = QStyle::PE_PanelLineEdit;
+        QStyleOptionFrameV3 opt;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.lineWidth = 1; // jens : this must be non-zero
+        m_style->initStyleOption(&opt);
+        qApp->style()->drawPrimitive(control, &opt, painter, 0);
+    }
+    else if (type == QLatin1String("slidergroove")) {
+        QStyle::ComplexControl control = QStyle::CC_Slider;
+        QStyleOptionSlider opt;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.minimum = 0;
+        opt.maximum = 100;
+        opt.subControls |= (QStyle::SC_SliderGroove);
+        opt.activeSubControls = QStyle::SC_SliderHandle;
+        m_style->initStyleOption(&opt);
+        qApp->style()->drawComplexControl(control, &opt, painter, 0);
+    }
+    else if (type == QLatin1String("combobox")) {
+        QStyle::ComplexControl control = QStyle::CC_ComboBox;
+        QStyleOptionComboBox opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        m_dummywidget.activateWindow();
+        qApp->style()->drawComplexControl(control, &opt, painter, &m_dummywidget);
+    }
+    else if (type == QLatin1String("spinbox")) {
+        QStyle::ComplexControl control = QStyle::CC_SpinBox;
+        QStyleOptionSpinBox opt;
+        opt.rect = QRect(0, 0, width(), height());
+        opt.frame = true;
+        m_style->initStyleOption(&opt);
+        if (m_style->value() & 0x1)
+            opt.activeSubControls = QStyle::SC_SpinBoxUp;
+        else if (m_style->value() & (1<<1))
+            opt.activeSubControls = QStyle::SC_SpinBoxDown;
+        opt.subControls |= QStyle::SC_SpinBoxDown;
+        opt.subControls |= QStyle::SC_SpinBoxUp;
+        if (m_style->value() & (1<<2))
+            opt.stepEnabled |= QAbstractSpinBox::StepUpEnabled;
+        if (m_style->value() & (1<<3))
+            opt.stepEnabled |= QAbstractSpinBox::StepDownEnabled;
+        qApp->style()->drawComplexControl(control, &opt, painter, 0);
+    }
+    else if (type == QLatin1String("slider")) {
+        QStyle::ComplexControl control = QStyle::CC_Slider;
+        QStyleOptionSlider opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        opt.minimum = m_style->minimum();
+        opt.maximum = m_style->maximum();
+        opt.tickPosition = QSlider::TicksBelow;
+        opt.sliderPosition = m_style->value();
+        opt.tickInterval = 1200 / (opt.maximum - opt.minimum);
+        opt.sliderValue = m_style->value();
+        opt.subControls = QStyle::SC_SliderTickmarks | QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
+        opt.activeSubControls = QStyle::SC_None;
+        qApp->style()->drawComplexControl(control, &opt, painter, 0);
+    }
+    else if (type == QLatin1String("progressbar")) {
+        QStyle::ControlElement control = QStyle::CE_ProgressBar;
+        QStyleOptionProgressBarV2 opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        opt.minimum = m_style->minimum();
+        opt.maximum = m_style->maximum();
+        opt.progress = m_style->value();
+        qApp->style()->drawControl(control, &opt, painter, &m_dummywidget);
+    }
+    else if (type == QLatin1String("toolbar")) {
+        QStyle::ControlElement control = QStyle::CE_ToolBar;
+        QStyleOptionToolBar opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        QMainWindow mw;
+        QWidget w(&mw);
+        qApp->style()->drawControl(control, &opt, painter, &w);
+    }
+    else if (type == QLatin1String("groupbox")) {
+        QStyle::ComplexControl control = QStyle::CC_GroupBox;
+        QStyleOptionGroupBox opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        opt.text = m_style->text();
+        opt.lineWidth = 1;
+        opt.subControls = QStyle::SC_GroupBoxLabel;
+        // oxygen crashes if we dont pass a widget
+        qApp->style()->drawComplexControl(control, &opt, painter, &m_dummywidget);
+    }
+    else if (type == QLatin1String("scrollbar")) {
+        QStyle::ComplexControl control = QStyle::CC_ScrollBar;
+        QStyleOptionSlider opt;
+        opt.rect = QRect(0, 0, width(), height());
+        m_style->initStyleOption(&opt);
+        opt.minimum = m_style->minimum();
+        opt.maximum = m_style->maximum();
+        opt.pageStep = m_style->horizontal() ? width() : height();
+        opt.orientation = m_style->horizontal() ? Qt::Horizontal : Qt::Vertical;
+        opt.sliderPosition = m_style->value();
+        opt.sliderValue = m_style->value();
+        opt.activeSubControls = (m_style->activeControl() == QLatin1String("up"))
+                                ? QStyle::SC_ScrollBarSubLine :
+                                (m_style->activeControl() == QLatin1String("down")) ?
+                                QStyle::SC_ScrollBarAddLine:
+                                QStyle::SC_ScrollBarSlider;
+
+        opt.sliderValue = m_style->value();
+        opt.subControls = QStyle::SC_All;
+        qApp->style()->drawComplexControl(control, &opt, painter, &m_dummywidget);
+    }
+}
diff --git a/components/styleitem/qstyleitem.h b/components/styleitem/qstyleitem.h
new file mode 100644
index 000000000..5d195252a
--- /dev/null
+++ b/components/styleitem/qstyleitem.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STYLEWRAPPER_H
+#define STYLEWRAPPER_H
+
+#include <QDeclarativeItem>
+#include <QtGui/QStyle>
+#include <QtGui>
+#include <QEvent>
+
+/**
+ * This class adds experimental support for
+ * animated progressbars
+ */
+class AnimWidget: public QProgressBar
+{
+Q_OBJECT
+public:
+    AnimWidget(QWidget *parent = 0):
+        QProgressBar(parent) {
+        setMaximum(100);
+        setMinimum(0);
+        setValue(50);
+        // setAttribute(Qt::WA_WState_InPaintEvent);
+        // setAttribute(Qt::WA_WState_Visible, true);
+    }
+public:
+    bool event(QEvent *e){
+        // emit updateRequest();
+        return QProgressBar::event(e);
+    }
+signals:
+    void updateRequest();
+};
+
+class QStyleItem: public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY( bool sunken READ sunken WRITE setSunken NOTIFY sunkenChanged)
+    Q_PROPERTY( bool raised READ raised WRITE setRaised NOTIFY raisedChanged)
+    Q_PROPERTY( bool active READ active WRITE setActive NOTIFY activeChanged)
+    Q_PROPERTY( bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+    Q_PROPERTY( bool selected READ selected WRITE setSelected NOTIFY selectedChanged)
+    Q_PROPERTY( bool focus READ focus WRITE setFocus NOTIFY focusChanged)
+    Q_PROPERTY( bool on READ on WRITE setOn NOTIFY onChanged)
+    Q_PROPERTY( bool hover READ hover WRITE setHover NOTIFY hoverChanged)
+    Q_PROPERTY( bool horizontal READ horizontal WRITE setHorizontal NOTIFY horizontalChanged)
+    Q_PROPERTY( QString elementType READ elementType WRITE setElementType NOTIFY elementTypeChanged)
+    Q_PROPERTY( QString text READ text WRITE setText NOTIFY textChanged)
+    Q_PROPERTY( QString activeControl READ activeControl WRITE setActiveControl NOTIFY activeControlChanged)
+
+    // For range controls
+    Q_PROPERTY( int minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
+    Q_PROPERTY( int maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
+    Q_PROPERTY( int value READ value WRITE setValue NOTIFY valueChanged)
+
+public:
+    QStyleItem(QObject *parent = 0);
+
+    bool sunken() const { return m_sunken; }
+    bool raised() const { return m_raised; }
+    bool active() const { return m_active; }
+    bool enabled() const { return m_enabled; }
+    bool selected() const { return m_selected; }
+    bool focus() const { return m_focus; }
+    bool on() const { return m_on; }
+    bool hover() const { return m_hover; }
+    bool horizontal() const { return m_horizontal; }
+    int minimum() const { return m_minimum; }
+    int maximum() const { return m_maximum; }
+    int value() const { return m_value; }
+    QString elementType() const { return m_type; }
+    QString text() const { return m_text; }
+    QString activeControl() const { return m_activeControl; }
+
+    void setSunken(bool sunken) { if (m_sunken != sunken) {m_sunken = sunken; emit sunkenChanged();}}
+    void setRaised(bool raised) { if (m_raised!= raised) {m_raised = raised; emit raisedChanged();}}
+    void setActive(bool active) { if (m_active!= active) {m_active = active; emit activeChanged();}}
+    void setEnabled(bool enabled) { if (m_enabled!= enabled) {m_enabled = enabled; emit enabledChanged();}}
+    void setSelected(bool selected) { if (m_selected!= selected) {m_selected = selected; emit selectedChanged();}}
+    void setFocus(bool focus) { if (m_focus != focus) {m_focus = focus; emit focusChanged();}}
+    void setOn(bool on) { if (m_on != on) {m_on = on ; emit onChanged();}}
+    void setHover(bool hover) { if (m_hover != hover) {m_hover = hover ; emit hoverChanged();}}
+    void setHorizontal(bool horizontal) { if (m_horizontal != horizontal) {m_horizontal = horizontal; emit horizontalChanged();}}
+    void setMinimum(int minimum) { if (m_minimum!= minimum) {m_minimum = minimum; emit minimumChanged();}}
+    void setMaximum(int maximum) { if (m_maximum != maximum) {m_maximum = maximum; emit maximumChanged();}}
+    void setValue(int value) { if (m_value!= value) {m_value = value; emit valueChanged();}}
+    void setElementType(const QString &str) { if (m_type != str) {m_type = str; emit elementTypeChanged();}}
+    void setText(const QString &str) { if (m_text != str) {m_text = str; emit textChanged();}}
+    void setActiveControl(const QString &str) { if (m_activeControl != str) {m_activeControl = str; emit activeControlChanged();}}
+
+    virtual void initStyleOption(QStyleOption *opt) const;
+public Q_SLOTS:
+    int pixelMetric(const QString&) const;    
+    QVariant styleHint(const QString&) const;
+    QSize sizeFromContents(int width, int height) const;
+
+Q_SIGNALS:
+    void elementTypeChanged();
+    void textChanged();
+    void sunkenChanged();
+    void raisedChanged();
+    void activeChanged();
+    void enabledChanged();
+    void selectedChanged();
+    void focusChanged();
+    void onChanged();
+    void hoverChanged();
+    void horizontalChanged();
+    void minimumChanged();
+    void maximumChanged();
+    void valueChanged();
+    void activeControlChanged();
+
+protected:
+    QString m_type;
+    QString m_text;
+    QString m_activeControl;
+    bool m_sunken;
+    bool m_raised;
+    bool m_active;
+    bool m_enabled;
+    bool m_selected;
+    bool m_focus;
+    bool m_hover;
+    bool m_on;
+    bool m_horizontal;
+    int m_minimum;
+    int m_maximum;
+    int m_value;
+    AnimWidget m_dummywidget;
+};
+
+class QStyleBackground: public QDeclarativeItem
+{
+    Q_OBJECT
+public:
+    Q_PROPERTY( QStyleItem* style READ style WRITE setStyle NOTIFY styleChanged)
+
+    QStyleBackground(QDeclarativeItem *parent = 0);
+    void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+public Q_SLOTS:
+    QStyleItem *style(){return m_style;}
+    void setStyle(QStyleItem *style);
+    void updateItem(){update();}
+    QString hitTest(int x, int y) const;
+    QRect subControlRect(const QString &subcontrolString) const;
+
+Q_SIGNALS:
+    void styleChanged();
+
+private:
+    AnimWidget m_dummywidget;
+    QWidget *m_menu;
+    QStyleItem *m_style;
+};
+
+#endif //STYLEWRAPPER_H
diff --git a/components/styleitem/qstyleplugin.cpp b/components/styleitem/qstyleplugin.cpp
new file mode 100644
index 000000000..05cb45c56
--- /dev/null
+++ b/components/styleitem/qstyleplugin.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+ 
+#include <qdeclarative.h>
+#include "qstyleplugin.h"
+#include "qstyleitem.h"
+
+#include <qdeclarativeextensionplugin.h>
+
+#include <qdeclarativeengine.h>
+#include <qdeclarative.h>
+#include <qdeclarativeitem.h>
+#include <qdeclarativeimageprovider.h>
+#include <qdeclarativeview.h>
+#include <QApplication>
+#include <QImage>
+
+// Load icons from desktop theme
+class DesktopIconProvider : public QDeclarativeImageProvider
+{
+public:
+    DesktopIconProvider()
+        : QDeclarativeImageProvider(QDeclarativeImageProvider::Pixmap)
+    {
+    }
+
+    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
+    {
+        int pos = id.lastIndexOf('/');
+        QString iconName = id.right(id.length() - pos);
+        int width = qApp->style()->pixelMetric(QStyle::PM_ToolBarIconSize);
+        return QIcon::fromTheme(iconName).pixmap(width);
+    }
+};
+
+void StylePlugin::registerTypes(const char *uri)
+{
+    qmlRegisterType<QStyleItem>(uri, 1, 0, "QStyleItem");
+    qmlRegisterType<QStyleBackground>(uri, 1, 0, "QStyleBackground");
+}
+
+void StylePlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)
+{
+    engine->addImageProvider("desktoptheme", new DesktopIconProvider);
+}
+
+Q_EXPORT_PLUGIN2(styleplugin, StylePlugin);
diff --git a/components/styleitem/qstyleplugin.h b/components/styleitem/qstyleplugin.h
new file mode 100644
index 000000000..45aff70f7
--- /dev/null
+++ b/components/styleitem/qstyleplugin.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STYLEPLUGIN_H
+#define STYLEPLUGIN_H
+
+#include <QDeclarativeExtensionPlugin>
+#include <QtScript/QScriptValue>
+#include <QtCore/QTimer>
+
+class StylePlugin : public QDeclarativeExtensionPlugin
+{
+    Q_OBJECT
+public:
+    void registerTypes(const char *uri);
+    void initializeEngine(QDeclarativeEngine *engine, const char *uri);
+};
+
+#endif // STYLEPLUGIN_H
diff --git a/components/styleitem/styleitem.pro b/components/styleitem/styleitem.pro
new file mode 100644
index 000000000..b254cd1eb
--- /dev/null
+++ b/components/styleitem/styleitem.pro
@@ -0,0 +1,38 @@
+TEMPLATE = lib
+CONFIG += qt plugin
+QT += declarative
+QT += script
+ 
+TARGET  = styleplugin
+
+DESTDIR = ..\\plugin
+OBJECTS_DIR = tmp
+MOC_DIR = tmp
+
+HEADERS += qstyleplugin.h \
+           qstyleitem.h
+
+SOURCES += qstyleplugin.cpp \
+	   qstyleitem.cpp
+           
+
+OTHER_FILES += \
+    ../widgets/Button.qml \
+    ../widgets/CheckBox.qml \
+    ../widgets/ChoiceList.qml \
+    ../widgets/GroupBox.qml \
+    ../widgets/ProgressBar.qml \
+    ../widgets/RadioButton.qml \
+    ../widgets/ScrollArea.qml \
+    ../widgets/ScrollBar.qml \
+    ../widgets/Slider.qml \
+    ../widgets/SpinBox.qml \
+    ../widgets/Switch.qml \
+    ../widgets/TextArea.qml \
+    ../widgets/TextField.qml \
+    ../widgets/ToolBar.qml \
+    ../widgets/ToolButton.qml \
+    ../gallery.qml \
+    ../widgets/Tab.qml \
+    ../widgets/TabBar.qml \
+    ../widgets/TabFrame.qml
diff --git a/src/Button.qml b/src/Button.qml
new file mode 100644
index 000000000..496d37df2
--- /dev/null
+++ b/src/Button.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Button {
+    id:button
+
+    property int buttonHeight: Math.max(22, styleitem.sizeFromContents(100, 6).height)
+    height: buttonHeight
+
+    QStyleItem {
+        id:styleitem
+        elementType:"button"
+        sunken: pressed
+        raised: !pressed
+        hover: containsMouse
+        enabled:button.enabled
+        text:button.text
+    }
+
+    background:
+    QStyleBackground {
+        style:styleitem
+        anchors.fill:parent
+    }
+}
+
diff --git a/src/ButtonRow.qml b/src/ButtonRow.qml
new file mode 100644
index 000000000..623c5f442
--- /dev/null
+++ b/src/ButtonRow.qml
@@ -0,0 +1,5 @@
+import QtQuick 1.0
+import "../../../components" as Components
+
+Components.ButtonRow {
+}
diff --git a/src/CheckBox.qml b/src/CheckBox.qml
new file mode 100644
index 000000000..632dce2d4
--- /dev/null
+++ b/src/CheckBox.qml
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.CheckBox{
+    id:checkbox
+    property variant text
+    width:100
+    height:18
+
+    background: QStyleBackground {
+        id:styleitem
+        style:QStyleItem {
+            elementType:"checkbox"
+            sunken:pressed
+            on:checked || pressed
+            hover:containsMouse
+            text:checkbox.text
+            enabled:checkbox.enabled
+        }
+    }
+    checkmark: null
+}
+
diff --git a/src/ChoiceList.qml b/src/ChoiceList.qml
new file mode 100644
index 000000000..5015fbefb
--- /dev/null
+++ b/src/ChoiceList.qml
@@ -0,0 +1,52 @@
+import QtQuick 1.0
+import "../../../components" 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 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"}
+    }
+}
diff --git a/src/GroupBox.qml b/src/GroupBox.qml
new file mode 100644
index 000000000..0d45810d1
--- /dev/null
+++ b/src/GroupBox.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Item {
+    width:200
+    height:46
+
+    property alias text: styleitem.text
+    default property alias children: content.children
+    property bool checkable: false
+
+    QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            id:styleitem
+            elementType:"groupbox"
+        }
+
+        Item {
+            id:content
+            anchors.topMargin:22
+            anchors.leftMargin:6
+            anchors.fill:parent
+        }
+    }
+}
diff --git a/src/ProgressBar.qml b/src/ProgressBar.qml
new file mode 100644
index 000000000..bf29bcac9
--- /dev/null
+++ b/src/ProgressBar.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.ProgressBar {
+    id:progressbar
+
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 15).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    height: buttonHeight
+
+    background: QStyleBackground{
+        anchors.fill:parent
+        style: QStyleItem {
+            elementType:"progressbar"
+
+            // XXX: since desktop uses int instead of real, the progressbar
+            // range [0..1] must be stretched to a good precision
+            property int factor : 1000000
+
+            value:   progressbar.value * factor
+            minimum: indeterminate ? 0 : progressbar.minimumValue * factor
+            maximum: indeterminate ? 0 : progressbar.maximumValue * factor
+            enabled: progressbar.enabled
+        }
+    }
+    indeterminateProgress:null
+    progress: null
+}
+
diff --git a/src/RadioButton.qml b/src/RadioButton.qml
new file mode 100644
index 000000000..3c2c3e547
--- /dev/null
+++ b/src/RadioButton.qml
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.RadioButton{
+    id:radiobutton
+    property variant text
+    width:110
+    height:18
+
+    background: QStyleBackground {
+
+        style: QStyleItem{
+            elementType:"radiobutton"
+            sunken:pressed
+            on:checked || pressed
+            hover:containsMouse
+            text:radiobutton.text
+            enabled:radiobutton.enabled
+        }
+    }
+    checkmark: null
+}
+
diff --git a/src/ScrollArea.qml b/src/ScrollArea.qml
new file mode 100644
index 000000000..3a904ddeb
--- /dev/null
+++ b/src/ScrollArea.qml
@@ -0,0 +1,103 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+FocusScope {
+    id:scrollarea
+    width: 100
+    height: 100
+
+    property int contentMargin: 1
+    property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    property int frameWidth: styleitem.pixelMetric("defaultframewidth");
+    property int contentHeight : content.childrenRect.height
+    property int contentWidth: content.childrenRect.width
+    property alias color: flickable.color
+    property bool frame: true
+    property bool highlightOnFocus: false
+
+    default property alias children: content.children
+
+    property int contentY
+    property int contentX
+
+    property bool frameAroundContents: styleitem.styleHint("framearoundcontents")
+
+    onContentYChanged: {
+        vscrollbar.value = contentY
+    }
+
+    onContentXChanged: {
+        hscrollbar.value = contentX
+    }
+
+    QStyleBackground {
+        style: QStyleItem{
+            id:styleitem
+            elementType: frame ? "frame" : ""
+            sunken: true
+        }
+        anchors.fill: parent
+        anchors.rightMargin: (frameAroundContents && vscrollbar.visible) ? vscrollbar.width + 4 : -frameWidth
+        anchors.bottomMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth
+        anchors.topMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth
+
+        Rectangle {
+            id:flickable
+            color: "transparent"
+            anchors.fill: parent
+            anchors.margins: frame ? 2 : 0
+            clip: true
+
+            Item {
+                id: docmargins
+                anchors.fill:parent
+                anchors.margins:contentMargin
+                Item {
+                    id: content
+                    x: -scrollarea.contentX
+                    y: -scrollarea.contentY
+                }
+            }
+        }
+    }
+
+    ScrollBar {
+        id: hscrollbar
+        orientation: Qt.Horizontal
+        visible: contentWidth > flickable.width
+        maximumValue: contentWidth > flickable.width ? scrollarea.contentWidth - flickable.width : 0
+        minimumValue: 0
+        anchors.bottom: parent.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.rightMargin: { return (frame ? 1 : 0) + ( vscrollbar.visible ? __scrollbarExtent : 0) }
+        onValueChanged: contentX = value
+    }
+
+    ScrollBar {
+        id: vscrollbar
+        orientation: Qt.Vertical
+        visible: contentHeight > flickable.height
+        maximumValue: contentHeight > flickable.height ? scrollarea.contentHeight - flickable.height : 0
+        minimumValue: 0
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        anchors.bottomMargin:  { return (frame ? 1 : 0) + (hscrollbar.visible ? __scrollbarExtent : 0) }
+        onValueChanged: contentY = value
+    }
+
+    QStyleBackground {
+        z:2
+        anchors.fill:parent
+        anchors.margins:-2
+        anchors.rightMargin:-4
+        anchors.bottomMargin:-4
+        visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget")
+        style: QStyleItem {
+            id:framestyle
+            elementType:"focusframe"
+        }
+    }
+}
diff --git a/src/ScrollBar.qml b/src/ScrollBar.qml
new file mode 100644
index 000000000..ea822b62e
--- /dev/null
+++ b/src/ScrollBar.qml
@@ -0,0 +1,109 @@
+import QtQuick 1.1
+import "../../../components" as Components
+import "../plugin"
+
+MouseArea {
+    id:scrollbar
+    property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    implicitWidth:orientation == Qt.Horizontal ? 200 : __scrollbarExtent;
+    implicitHeight:orientation == Qt.Horizontal ? __scrollbarExtent : 200
+
+    property int orientation : Qt.Horizontal
+    property alias minimumValue: slider.minimumValue
+    property alias maximumValue: slider.maximumValue
+    property alias value: slider.value
+
+    property bool upPressed;
+    property bool downPressed;
+    property bool __autoincrement: false
+
+    // Update hover item
+    onEntered: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY)
+    onExited: styleitem.activeControl = "none"
+    onMouseXChanged: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY)
+    hoverEnabled:true
+
+    Timer { running: upPressed || downPressed; interval: 350 ; onTriggered: __autoincrement = true }
+    Timer { running: __autoincrement; interval: 60 ; repeat: true ;
+        onTriggered: upPressed ? decrement() : increment() }
+
+    onPressed: {
+        var control = bgitem.hitTest(mouseX,mouseY)
+        if (control == "up") {
+            upPressed = true
+        } else if (control == "down") {
+            downPressed = true
+        }
+    }
+
+    onReleased: {
+        __autoincrement = false;
+        if (upPressed) {
+            upPressed = false;
+            decrement()
+        } else if (downPressed) {
+            increment()
+            downPressed = false;
+        }
+    }
+
+    function increment() {
+        value += 30
+        if (value > maximumValue)
+            value = maximumValue
+    }
+
+    function decrement() {
+        value -= 30
+        if (value < minimumValue)
+            value = minimumValue
+    }
+
+    QStyleBackground {
+        id:bgitem
+        anchors.fill:parent
+        style: QStyleItem {
+            id:styleitem
+            elementType: "scrollbar"
+            hover: activeControl != "none"
+            activeControl: "none"
+            sunken: upPressed | downPressed
+            minimum: slider.minimumValue
+            maximum: slider.maximumValue
+            value: slider.value
+            horizontal: orientation == Qt.Horizontal
+            enabled: parent.enabled
+        }
+    }
+
+    property variant handleRect
+    function updateHandle() {
+        handleRect = bgitem.subControlRect("handle")
+        var grooveRect = bgitem.subControlRect("groove");
+        var extra = 0
+        if (orientation == Qt.Vertical) {
+            slider.anchors.topMargin = grooveRect.y + extra
+            slider.anchors.bottomMargin = height - grooveRect.y - grooveRect.height + extra
+        } else {
+            slider.anchors.leftMargin = grooveRect.x + extra
+            slider.anchors.rightMargin = width - grooveRect.x - grooveRect.width + extra
+        }
+    }
+
+    onValueChanged: updateHandle()
+    onMaximumValueChanged: updateHandle()
+    onMinimumValueChanged: updateHandle()
+    Component.onCompleted: updateHandle()
+    Components.Slider {
+        id:slider
+        anchors.fill:parent
+        orientation:scrollbar.orientation
+        leftMargin: (orientation === Qt.Horizontal) ? handleRect.width/2 : handleRect.height/2
+        rightMargin:leftMargin
+        handle: Item { width:orientation == Qt.Vertical ? handleRect.height : handleRect.width;
+                       height:orientation == Qt.Vertical ? handleRect.width : handleRect.height}
+        groove:null
+        valueIndicator:null
+        inverted:orientation != Qt.Horizontal
+    }
+}
diff --git a/src/Slider.qml b/src/Slider.qml
new file mode 100644
index 000000000..c6b9c9151
--- /dev/null
+++ b/src/Slider.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jens: ContainsMouse breaks drag functionality
+
+Components.Slider{
+    id:slider
+    minimumWidth:200
+
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 15).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    height: buttonHeight
+
+    groove: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"slider"
+            sunken: pressed
+            maximum:slider.maximumValue
+            minimum:slider.minimumValue
+            value:slider.value
+            horizontal:slider.orientation == Qt.Horizontal
+            enabled:slider.enabled
+        }
+    }
+
+    handle: null
+    valueIndicator: null
+}
diff --git a/src/SpinBox.qml b/src/SpinBox.qml
new file mode 100644
index 000000000..2db428cef
--- /dev/null
+++ b/src/SpinBox.qml
@@ -0,0 +1,91 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.SpinBox {
+    id:spinbox
+
+    property variant __upRect;
+    property variant __downRect;
+    property int __margin: (height -16)/2
+
+    // Align height with button
+    topMargin:__margin
+    bottomMargin:__margin
+
+    property int buttonHeight: edititem.sizeFromContents(100, 20).height
+    QStyleItem { id:edititem; elementType:"edit" }
+    height: buttonHeight
+    clip:false
+
+    background:
+        Item {
+        anchors.fill: parent
+        property variant __editRect
+
+        Rectangle {
+            id:editBackground
+            x: __editRect.x - 1
+            y: __editRect.y
+            width: __editRect.width
+            height: __editRect.height
+        }
+
+        Item {
+            id:focusFrame
+            anchors.fill: editBackground
+            visible:framestyle.styleHint("focuswidget")
+            QStyleBackground{
+                anchors.margins: -6
+                anchors.leftMargin: -5
+                anchors.fill: parent
+                visible:spinbox.activeFocus
+                style: QStyleItem {
+                    id:framestyle
+                    elementType:"focusframe"
+                }
+            }
+        }
+
+        function updateRect() {
+            __upRect = spinboxbg.subControlRect("up");
+            __downRect = spinboxbg.subControlRect("down");
+            __editRect = spinboxbg.subControlRect("edit");
+        }
+
+        Component.onCompleted:updateRect()
+        onWidthChanged:updateRect()
+        onHeightChanged:updateRect()
+
+        QStyleBackground {
+            id:spinboxbg
+            anchors.fill:parent
+            style: QStyleItem {
+                id: styleitem
+                elementType: "spinbox"
+                sunken: downPressed | upPressed
+                hover: containsMouse
+                focus: spinbox.activeFocus
+                enabled: spinbox.enabled
+                value: (upPressed? 1 : 0)           |
+                        (downPressed== 1 ? 1<<1 : 0) |
+                        (upEnabled? (1<<2) : 0)      |
+                        (downEnabled == 1 ? (1<<3) : 0)
+            }
+        }
+    }
+
+    up: Item {
+        x: __upRect.x
+        y: __upRect.y
+        width: __upRect.width
+        height: __upRect.height
+    }
+
+    down: Item {
+        x: __downRect.x
+        y: __downRect.y
+        width: __downRect.width
+        height: __downRect.height
+    }
+}
diff --git a/src/Switch.qml b/src/Switch.qml
new file mode 100644
index 000000000..b82817c9f
--- /dev/null
+++ b/src/Switch.qml
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Switch {
+    id:widget
+    minimumWidth:100
+    minimumHeight:30
+
+    groove:QStyleItem {
+        elementType:"edit"
+        sunken: true
+    }
+
+    handle: QStyleItem {
+        elementType:"button"
+        width:widget.width/2
+        height:widget.height-4
+        hover:containsMouse
+    }
+}
+
diff --git a/src/Tab.qml b/src/Tab.qml
new file mode 100644
index 000000000..e258185ba
--- /dev/null
+++ b/src/Tab.qml
@@ -0,0 +1,7 @@
+import Qt 4.7
+
+Item {
+    id:tab
+    anchors.fill:parent
+    property string title
+}
diff --git a/src/TabBar.qml b/src/TabBar.qml
new file mode 100644
index 000000000..2d891256f
--- /dev/null
+++ b/src/TabBar.qml
@@ -0,0 +1,90 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+
+Item {
+    id: tabbar
+    property int tabHeight: styleitem.sizeFromContents(100, 24).height
+    height: tabHeight
+
+    property Item tabFrame
+    onTabFrameChanged:parent = tabFrame
+    visible: tabFrame ? tabFrame.tabsVisible : true
+    property int __overlap : styleitem.pixelMetric("tabvshift");
+    property string position: tabFrame ? tabFrame.position : "North"
+    property string tabBarAlignment: styleitem.styleHint("tabbaralignment");
+    property int tabOverlap: styleitem.pixelMetric("taboverlap");
+
+    function tab(index) {
+        for (var i = 0; i < tabrow.children.length; ++i) {
+            if (tabrow.children[i].tabindex == index) {
+                return tabrow.children[i]
+            }
+        }
+        return null;
+    }
+
+    QStyleItem {
+        id:styleitem
+        elementType: "tab"
+        text: "generic"
+    }
+
+    Row {
+        id:tabrow
+        states:
+        State {
+            when: tabBarAlignment == "center"
+            name: "centered"
+            AnchorChanges {
+                target:tabrow
+                anchors.horizontalCenter: tabbar.horizontalCenter
+            }
+        }
+        Repeater {
+            id:repeater
+            model: tabFrame ? tabFrame.tabs.length : null
+            delegate: Item {
+                id:tab
+                property int tabindex: index
+                property bool selected : tabFrame.current == index
+                width: textitem.width + 42
+                height: tabHeight
+                z: selected ? 1 : -1
+
+                QStyleBackground {
+                    style: QStyleItem {
+                        id:style
+                        elementType: "tab"
+                        selected: tab.selected
+                        text: tabbar.position
+
+                        activeControl: tabFrame.count == 1 ?
+                                           "only" :
+                        index == 0 ? "beginning" :
+                            index == tabFrame.count-1 ? "end" : "middle"
+                    }
+                    anchors.leftMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle" || style.activeControl == "end")
+                                        && tab.selected ? -__overlap : 0)
+
+                    anchors.rightMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle"  || style.activeControl == "beginning")
+                                         && tab.selected ? -__overlap : 0)
+                    anchors.fill:parent
+                }
+
+                Text {
+                    id:textitem
+                    anchors.centerIn:parent
+                    text:  tabFrame.tabs[index].title
+                    elide: Text.ElideRight
+                }
+
+                MouseArea {
+                    anchors.fill: parent
+                    onPressed: tabFrame.current = index
+                }
+            }
+        }
+    }
+}
diff --git a/src/TabFrame.qml b/src/TabFrame.qml
new file mode 100644
index 000000000..01896e753
--- /dev/null
+++ b/src/TabFrame.qml
@@ -0,0 +1,72 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Item{
+    id: tabWidget
+    width:100
+    height:100
+    property TabBar tabbar
+    property int current: 0
+    property int count: stack.children.length
+    property bool frame:true
+    property bool tabsVisible: true
+    property string position: "North"
+    default property alias tabs : stack.children
+
+    onCurrentChanged: __setOpacities()
+    Component.onCompleted: __setOpacities()
+    onTabbarChanged: {
+        tabbar.tabFrame = tabWidget
+        tabbar.anchors.top = tabWidget.top
+        tabbar.anchors.left = tabWidget.left
+        tabbar.anchors.right = tabWidget.right
+    }
+
+    property int __baseOverlap : style.pixelMetric("tabbaseoverlap");
+    function __setOpacities() {
+        for (var i = 0; i < stack.children.length; ++i) {
+            stack.children[i].opacity = (i == current ? 1 : 0)
+        }
+    }
+
+    QStyleBackground {
+        id: frame
+        z:-1
+        style: QStyleItem {
+            id:style
+            elementType: "tabframe"
+            text: position
+            value: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).x : 0
+            minimum: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).width : 0
+        }
+        anchors.fill:parent
+        Item {
+            id:stack
+            anchors.fill:parent
+            anchors.margins: frame ? 2 : 0
+        }
+        anchors.topMargin: tabbar && tabsVisible && position == "North" ? tabbar.height - __baseOverlap : 0
+
+        states: [
+            State {
+                name: "South"
+                when: position == "South" && tabbar!= undefined
+                PropertyChanges {
+                    target: frame
+                    anchors.topMargin: 0
+                    anchors.bottomMargin: tabbar ? tabbar.height - __baseOverlap: 0
+                }
+                PropertyChanges {
+                    target: tabbar
+                    anchors.topMargin: -__baseOverlap
+                }
+                AnchorChanges {
+                    target: tabbar
+                    anchors.top: frame.bottom
+                    anchors.bottom: undefined
+                }
+            }
+        ]
+    }
+}
diff --git a/src/TextArea.qml b/src/TextArea.qml
new file mode 100644
index 000000000..93ad8f3d9
--- /dev/null
+++ b/src/TextArea.qml
@@ -0,0 +1,44 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.TextArea {
+    id:textarea
+    leftMargin:12
+    rightMargin:12
+    minimumWidth:200
+    desktopBehavior:true
+    placeholderText:""
+    clip:false
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 14).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    minimumHeight: buttonHeight
+
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"edit"
+            sunken:true
+            focus:textarea.activeFocus
+        }
+    }
+
+    Item{
+        id:focusFrame
+        anchors.fill: textarea
+        parent:textarea.parent
+        visible:framestyle.styleHint("focuswidget")
+        QStyleBackground{
+            anchors.margins: -2
+            anchors.rightMargin:-4
+            anchors.bottomMargin:-4
+            anchors.fill: parent
+            visible:textarea.activeFocus
+            style: QStyleItem {
+                id:framestyle
+                elementType:"focusframe"
+            }
+        }
+    }
+}
diff --git a/src/TextField.qml b/src/TextField.qml
new file mode 100644
index 000000000..260584e95
--- /dev/null
+++ b/src/TextField.qml
@@ -0,0 +1,52 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.TextField {
+    id:textfield
+    minimumWidth:200
+    desktopBehavior:true
+    placeholderText:""
+    topMargin:2
+    bottomMargin:2
+    leftMargin:6
+    rightMargin:6
+    width:200
+    height: editItem.sizeFromContents(100, 20).height
+    clip:false
+
+    QStyleItem {
+        id:editItem
+        elementType:"edit"
+        sunken:true
+        focus:textfield.activeFocus
+        hover:containsMouse
+    }
+
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"edit"
+            sunken:true
+            focus:textfield.activeFocus
+        }
+    }
+
+    Item{
+        id:focusFrame
+        anchors.fill: textfield
+        parent:textfield
+        visible:framestyle.styleHint("focuswidget")
+        QStyleBackground{
+            anchors.margins: -2
+            anchors.rightMargin:-4
+            anchors.bottomMargin:-4
+            anchors.fill: parent
+            visible:textfield.activeFocus
+            style: QStyleItem {
+                id:framestyle
+                elementType:"focusframe"
+            }
+        }
+    }
+}
diff --git a/src/TextScrollArea.qml b/src/TextScrollArea.qml
new file mode 100644
index 000000000..2a7deab68
--- /dev/null
+++ b/src/TextScrollArea.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+ScrollArea {
+    id:area
+    color: "white"
+    width: 280
+    height: 120
+    contentWidth: 200
+
+    property alias text: edit.text
+    property alias wrapMode: edit.wrapMode
+    highlightOnFocus: true
+
+    TextEdit {
+        id: edit
+        text: loremIpsum + loremIpsum;
+        wrapMode: TextEdit.WordWrap;
+        width: area.contentWidth
+        selectByMouse:true
+
+        // keep textcursor within scrollarea
+        onCursorRectangleChanged:
+            if (cursorRectangle.y >= area.contentY + area.height - 1.5*cursorRectangle.height)
+                area.contentY = cursorRectangle.y - area.height + 1.5*cursorRectangle.height
+            else if (cursorRectangle.y < area.contentY)
+                area.contentY = cursorRectangle.y
+
+    }
+}
diff --git a/src/ToolBar.qml b/src/ToolBar.qml
new file mode 100644
index 000000000..ce61382ee
--- /dev/null
+++ b/src/ToolBar.qml
@@ -0,0 +1,12 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+QStyleBackground {
+    id:styleitem
+    width:200
+    height:60
+
+    style: QStyleItem{elementType:"toolbar"}
+}
+
diff --git a/src/ToolButton.qml b/src/ToolButton.qml
new file mode 100644
index 000000000..98b2dfebf
--- /dev/null
+++ b/src/ToolButton.qml
@@ -0,0 +1,18 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Button {
+    id:button
+    minimumWidth:30
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem {
+            elementType: "toolbutton"
+            on: pressed | checked
+            sunken: pressed
+            raised: containsMouse
+            hover: containsMouse
+        }
+    }
+}
diff --git a/src/components/ButtonGroup.js b/src/components/ButtonGroup.js
new file mode 100644
index 000000000..f2d000029
--- /dev/null
+++ b/src/components/ButtonGroup.js
@@ -0,0 +1,127 @@
+var self;
+var clickHandlers = [];
+var visibleButtons = [];
+var nonVisibleButtons = [];
+var direction;
+var exclusive;
+
+function create(that, options) {
+    self = that;
+    direction = options.direction || Qt.Horizontal;
+    exclusive = self.exclusive|| options.exclusive;
+    self.childrenChanged.connect(rebuild);
+//    self.widthChanged.connect(resizeChildren);
+    build();
+}
+
+function isButton(item) {
+    if (item && item["__position"] !== undefined)
+        return true;
+    return false;
+}
+
+function hasChecked(item) {
+    if (item && item["checked"] !== undefined)
+        return true;
+    return false;
+}
+
+function destroy() {
+    self.childrenChanged.disconnect(rebuild);
+//    self.widthChanged.disconnect(resizeChildren);
+    cleanup();
+}
+
+function build() {
+    visibleButtons = [];
+    nonVisibleButtons = [];
+
+    for (var i = 0, item; (item = self.children[i]); i++) {
+        if (!hasChecked(item))
+            continue;
+
+        item.visibleChanged.connect(rebuild); // Not optimal, but hardly a bottleneck in your app
+        if (!item.visible) {
+            nonVisibleButtons.push(item);
+            continue;
+        }
+        visibleButtons.push(item);
+
+        if (exclusive && hasChecked(item)) {
+            if (item["checkable"]!==undefined) {
+                item.checkable = true;
+            }
+            clickHandlers[i] = checkExclusive(item);
+            item.clicked.connect(clickHandlers[i]);
+        }
+    }
+
+    if (self.checkedButton && !self.checkedButton.visible)
+        self.checkedButton = undefined;
+
+    var nrButtons = visibleButtons.length;
+    if (nrButtons == 0)
+        return;
+
+    if (nrButtons == 1) {
+        finishButton(visibleButtons[0], "only");
+    } else {
+        finishButton(visibleButtons[0], direction == Qt.Horizontal ? "leftmost" : "top");
+        for (var i = 1; i < nrButtons - 1; i++)
+            finishButton(visibleButtons[i], direction == Qt.Horizontal ? "h_middle": "v_middle");
+        finishButton(visibleButtons[nrButtons - 1], direction == Qt.Horizontal ? "rightmost" : "bottom");
+    }
+}
+
+function finishButton(button, position) {
+    if (isButton(button)) {
+        button.__position = position;
+        if (direction == Qt.Vertical) {
+            button.anchors.left = self.left
+            button.anchors.right = self.right
+        }
+    }
+}
+
+function cleanup() {
+    visibleButtons.forEach(function(item, i) {
+        if (clickHandlers[i])
+            item.clicked.disconnect(clickHandlers[i]);
+        item.visibleChanged.disconnect(rebuild);
+    });
+    clickHandlers = [];
+
+    nonVisibleButtons.forEach(function(item, i) {
+        item.visibleChanged.disconnect(rebuild);
+    });
+}
+
+function rebuild() {
+    cleanup();
+    build();
+}
+
+function resizeChildren() {
+    if (direction != Qt.Horizontal)
+        return;
+
+    var extraPixels = self.width % visibleButtons;
+    var buttonSize = (self.width - extraPixels) / visibleButtons;
+    visibleButtons.forEach(function(item, i) {
+        if (!item || !item.visible)
+            return;
+        item.width = buttonSize + (extraPixels > 0 ? 1 : 0);
+        if (extraPixels > 0)
+            extraPixels--;
+    });
+}
+
+function checkExclusive(item) {
+    var button = item;
+    return function() {
+        for (var i = 0, ref; (ref = visibleButtons[i]); i++) {
+            ref.checked = button === ref;
+        }
+        self.checkedButton = button;
+    }
+}
diff --git a/src/components/components.pro b/src/components/components.pro
new file mode 100644
index 000000000..be0663d70
--- /dev/null
+++ b/src/components/components.pro
@@ -0,0 +1,49 @@
+TEMPLATE = subdirs # XXX: Avoid call the linker
+TARGETPATH = Qt/labs/components/custom
+
+symbian {
+    INSTALL_IMPORTS = /resource/qt/imports
+} else {
+    INSTALL_IMPORTS = $$[QT_INSTALL_IMPORTS]
+}
+
+QML_FILES = \
+        qmldir \
+        BasicButton.qml \
+        BusyIndicator.qml \
+        ButtonBlock.qml \
+        ButtonColumn.qml \
+        ButtonRow.qml \
+        ButtonGroup.js \
+        Button.qml \
+        CheckBox.qml \
+        ChoiceList.qml \
+        ProgressBar.qml \
+        RadioButton.qml \
+        ScrollDecorator.qml \
+        ScrollIndicator.qml \
+        Slider.qml \
+        SpinBox.qml \
+        Switch.qml \
+        TextArea.qml \
+        TextField.qml
+
+QML_DIRS = \
+        behaviors \
+        private \
+        styles \
+        visuals
+
+qmlfiles.files = $$QML_FILES
+qmlfiles.sources = $$QML_FILES
+qmlfiles.path = $$INSTALL_IMPORTS/$$TARGETPATH
+
+qmldirs.files = $$QML_DIRS
+qmldirs.sources = $$QML_DIRS
+qmldirs.path = $$INSTALL_IMPORTS/$$TARGETPATH
+
+INSTALLS += qmlfiles qmldirs
+
+symbian {
+    DEPLOYMENT += qmlfiles qmldirs
+}
diff --git a/src/components/qmldir b/src/components/qmldir
new file mode 100644
index 000000000..6e256a81d
--- /dev/null
+++ b/src/components/qmldir
@@ -0,0 +1,17 @@
+BasicButton 1.0 BasicButton.qml
+BusyIndicator 1.0 BusyIndicator.qml
+ButtonBlock 1.0 ButtonBlock.qml
+Button 1.0 Button.qml
+ButtonColumn 1.0 ButtonColumn.qml
+ButtonRow 1.0 ButtonRow.qml
+CheckBox 1.0 CheckBox.qml
+ChoiceList 1.0 ChoiceList.qml
+ProgressBar 1.0 ProgressBar.qml
+RadioButton 1.0 RadioButton.qml
+ScrollDecorator 1.0 ScrollDecorator.qml
+ScrollIndicator 1.0 ScrollIndicator.qml
+Slider 1.0 Slider.qml
+SpinBox 1.0 SpinBox.qml
+Switch 1.0 Switch.qml
+TextArea 1.0 TextArea.qml
+TextField 1.0 TextField.qml
diff --git a/src/images/folder_new.png b/src/images/folder_new.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d8bb9bd768d8e8ab785d95483ead02ae6800dc5
GIT binary patch
literal 1199
zcmV;g1W@~lP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101k9TSaeirbZlh+MsI9nWpZ;NRH|S>0000NbVXQnL3MO!Z*l-k
zVQ_CCLt$)TZDDR?a%E}Xks2xh001d;MObu1WpiV4X>fFDZ*BlWVRL0<Aa7<MN?~ht
zVjxp=Wod3@av)@7b7^O8po9f;000BJNkl<ZNQteLO^6&t6vuznRnt8)&TMwwuc%3g
z2L+Xg#E;-dLX;fTm|zS9BAz685^_-q9uyG|f}n_a(2IhCBC^TJQ#K*NgBpV$m_(v6
zF_>g`c6MfW=cA{)s-B0L%+9*2hHM@b)l|QFzxV#Hs#}Q&%d^*l_WY_}>aDt3Kzece
zdac!cscYUPuC`9W*HJk92_px7S~kFycI-lAJK{H5*Ic8E&yrT&@tI8VfYQZJ^~l(l
zmwip|#uxVO*{fCXra&~m+D)M1J<q-M(o_YJ-N2KO!4!9)i@N~{((3y=LS69o(vGrO
zId*svK%9I1q0Ns(S_gRVJHz3<CyrYKCr=*#c)D6YRLJYc6$)i;#1wY6Gc7ztQu%<|
z%y&DLl1=G}{I<c{8{aGdSnG2joc`^XMY0r&{j9rVbuJV9ywwc6OOU;Hp@YhjUvn5_
zmSlGSu)Fa5e&B{+0l-;iW~wBuWYH*3O%mybvOb5M`wVbPbq9Q%v^M5~Aos%}iJWyz
zPnT&lnhUmh??_V18P(#pwbv7wBlyxQWQX7A(KiM^NB!bn;@KZtgZ+2Eya-^er8GH7
zlC*j|g9-v3-n@mitA`mX97b^#d=1<bC_pSCF-RR`hQG?I@|iw=uCEvH;=Vmk_YbTv
z^=7?SSd7u!zu^H^j*c=>Dx=aIqXmef0C9hk*2YO{UlA4_C6ix|QhDZT75Y{knO;zV
zv+nIDwr*o+Xk<RT0tAvIrcx~-;+dSeiBNA~Me-5N@`spkluS5CYx+HE6D1(W!Ed+l
z;A8C=T|gYSMuNaIIeC7G=JoW+8O}}J!${vsiuq|GV&Vj1n`bT_pe1)QG4*-ZzYDO|
z5=A+jv;PSIur9}i$}L25F=3`HX`JRsZH}R#eyp88Ve^30k;@fGlK6iC-D=3tOpEiu
z3}|hzc0S22AnjCOOy-IKOPPqrrb_^9>IedjUM9eK|1T0*i-^A_6{Jg5fY7Kn>iICt
z0`2?LKBu5iorT^=AeX<i(tZ*V>h&5TG%mXZ?KsMa$kgwrf2GxI;;lnGC<)NYV01`m
za%95-+3-3-lf~!|tqgdDcY;eT&3cV<f1E+Ql$25iz$m2@5LK(QhsMXppV_!^MhC$^
z)4eit&U5tW_pVy49t0w#lrtSQ^zq{-zHrWOI)DDs%~ut@W6fss?6G5~#sE!6WCeu4
zAaHAEUXE3OQ$QI=l!%~|3TQVxL#HpxFb|}F6%pV4>34c@%}hFh{|2rA&Q3Ns=Tray
N002ovPDHLkV1nxxBC7xZ

literal 0
HcmV?d00001

diff --git a/src/plugin/qmldir b/src/plugin/qmldir
new file mode 100644
index 000000000..e8452efd6
--- /dev/null
+++ b/src/plugin/qmldir
@@ -0,0 +1 @@
+plugin styleplugin
diff --git a/src/styleitem/styleitem.pro b/src/styleitem/styleitem.pro
new file mode 100644
index 000000000..b254cd1eb
--- /dev/null
+++ b/src/styleitem/styleitem.pro
@@ -0,0 +1,38 @@
+TEMPLATE = lib
+CONFIG += qt plugin
+QT += declarative
+QT += script
+ 
+TARGET  = styleplugin
+
+DESTDIR = ..\\plugin
+OBJECTS_DIR = tmp
+MOC_DIR = tmp
+
+HEADERS += qstyleplugin.h \
+           qstyleitem.h
+
+SOURCES += qstyleplugin.cpp \
+	   qstyleitem.cpp
+           
+
+OTHER_FILES += \
+    ../widgets/Button.qml \
+    ../widgets/CheckBox.qml \
+    ../widgets/ChoiceList.qml \
+    ../widgets/GroupBox.qml \
+    ../widgets/ProgressBar.qml \
+    ../widgets/RadioButton.qml \
+    ../widgets/ScrollArea.qml \
+    ../widgets/ScrollBar.qml \
+    ../widgets/Slider.qml \
+    ../widgets/SpinBox.qml \
+    ../widgets/Switch.qml \
+    ../widgets/TextArea.qml \
+    ../widgets/TextField.qml \
+    ../widgets/ToolBar.qml \
+    ../widgets/ToolButton.qml \
+    ../gallery.qml \
+    ../widgets/Tab.qml \
+    ../widgets/TabBar.qml \
+    ../widgets/TabFrame.qml
diff --git a/src/widgets/Button.qml b/src/widgets/Button.qml
new file mode 100644
index 000000000..496d37df2
--- /dev/null
+++ b/src/widgets/Button.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Button {
+    id:button
+
+    property int buttonHeight: Math.max(22, styleitem.sizeFromContents(100, 6).height)
+    height: buttonHeight
+
+    QStyleItem {
+        id:styleitem
+        elementType:"button"
+        sunken: pressed
+        raised: !pressed
+        hover: containsMouse
+        enabled:button.enabled
+        text:button.text
+    }
+
+    background:
+    QStyleBackground {
+        style:styleitem
+        anchors.fill:parent
+    }
+}
+
diff --git a/src/widgets/ButtonRow.qml b/src/widgets/ButtonRow.qml
new file mode 100644
index 000000000..623c5f442
--- /dev/null
+++ b/src/widgets/ButtonRow.qml
@@ -0,0 +1,5 @@
+import QtQuick 1.0
+import "../../../components" as Components
+
+Components.ButtonRow {
+}
diff --git a/src/widgets/CheckBox.qml b/src/widgets/CheckBox.qml
new file mode 100644
index 000000000..632dce2d4
--- /dev/null
+++ b/src/widgets/CheckBox.qml
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.CheckBox{
+    id:checkbox
+    property variant text
+    width:100
+    height:18
+
+    background: QStyleBackground {
+        id:styleitem
+        style:QStyleItem {
+            elementType:"checkbox"
+            sunken:pressed
+            on:checked || pressed
+            hover:containsMouse
+            text:checkbox.text
+            enabled:checkbox.enabled
+        }
+    }
+    checkmark: null
+}
+
diff --git a/src/widgets/ChoiceList.qml b/src/widgets/ChoiceList.qml
new file mode 100644
index 000000000..5015fbefb
--- /dev/null
+++ b/src/widgets/ChoiceList.qml
@@ -0,0 +1,52 @@
+import QtQuick 1.0
+import "../../../components" 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 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"}
+    }
+}
diff --git a/src/widgets/GroupBox.qml b/src/widgets/GroupBox.qml
new file mode 100644
index 000000000..0d45810d1
--- /dev/null
+++ b/src/widgets/GroupBox.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Item {
+    width:200
+    height:46
+
+    property alias text: styleitem.text
+    default property alias children: content.children
+    property bool checkable: false
+
+    QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            id:styleitem
+            elementType:"groupbox"
+        }
+
+        Item {
+            id:content
+            anchors.topMargin:22
+            anchors.leftMargin:6
+            anchors.fill:parent
+        }
+    }
+}
diff --git a/src/widgets/ProgressBar.qml b/src/widgets/ProgressBar.qml
new file mode 100644
index 000000000..bf29bcac9
--- /dev/null
+++ b/src/widgets/ProgressBar.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.ProgressBar {
+    id:progressbar
+
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 15).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    height: buttonHeight
+
+    background: QStyleBackground{
+        anchors.fill:parent
+        style: QStyleItem {
+            elementType:"progressbar"
+
+            // XXX: since desktop uses int instead of real, the progressbar
+            // range [0..1] must be stretched to a good precision
+            property int factor : 1000000
+
+            value:   progressbar.value * factor
+            minimum: indeterminate ? 0 : progressbar.minimumValue * factor
+            maximum: indeterminate ? 0 : progressbar.maximumValue * factor
+            enabled: progressbar.enabled
+        }
+    }
+    indeterminateProgress:null
+    progress: null
+}
+
diff --git a/src/widgets/RadioButton.qml b/src/widgets/RadioButton.qml
new file mode 100644
index 000000000..3c2c3e547
--- /dev/null
+++ b/src/widgets/RadioButton.qml
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.RadioButton{
+    id:radiobutton
+    property variant text
+    width:110
+    height:18
+
+    background: QStyleBackground {
+
+        style: QStyleItem{
+            elementType:"radiobutton"
+            sunken:pressed
+            on:checked || pressed
+            hover:containsMouse
+            text:radiobutton.text
+            enabled:radiobutton.enabled
+        }
+    }
+    checkmark: null
+}
+
diff --git a/src/widgets/ScrollArea.qml b/src/widgets/ScrollArea.qml
new file mode 100644
index 000000000..3a904ddeb
--- /dev/null
+++ b/src/widgets/ScrollArea.qml
@@ -0,0 +1,103 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+FocusScope {
+    id:scrollarea
+    width: 100
+    height: 100
+
+    property int contentMargin: 1
+    property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    property int frameWidth: styleitem.pixelMetric("defaultframewidth");
+    property int contentHeight : content.childrenRect.height
+    property int contentWidth: content.childrenRect.width
+    property alias color: flickable.color
+    property bool frame: true
+    property bool highlightOnFocus: false
+
+    default property alias children: content.children
+
+    property int contentY
+    property int contentX
+
+    property bool frameAroundContents: styleitem.styleHint("framearoundcontents")
+
+    onContentYChanged: {
+        vscrollbar.value = contentY
+    }
+
+    onContentXChanged: {
+        hscrollbar.value = contentX
+    }
+
+    QStyleBackground {
+        style: QStyleItem{
+            id:styleitem
+            elementType: frame ? "frame" : ""
+            sunken: true
+        }
+        anchors.fill: parent
+        anchors.rightMargin: (frameAroundContents && vscrollbar.visible) ? vscrollbar.width + 4 : -frameWidth
+        anchors.bottomMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth
+        anchors.topMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth
+
+        Rectangle {
+            id:flickable
+            color: "transparent"
+            anchors.fill: parent
+            anchors.margins: frame ? 2 : 0
+            clip: true
+
+            Item {
+                id: docmargins
+                anchors.fill:parent
+                anchors.margins:contentMargin
+                Item {
+                    id: content
+                    x: -scrollarea.contentX
+                    y: -scrollarea.contentY
+                }
+            }
+        }
+    }
+
+    ScrollBar {
+        id: hscrollbar
+        orientation: Qt.Horizontal
+        visible: contentWidth > flickable.width
+        maximumValue: contentWidth > flickable.width ? scrollarea.contentWidth - flickable.width : 0
+        minimumValue: 0
+        anchors.bottom: parent.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.rightMargin: { return (frame ? 1 : 0) + ( vscrollbar.visible ? __scrollbarExtent : 0) }
+        onValueChanged: contentX = value
+    }
+
+    ScrollBar {
+        id: vscrollbar
+        orientation: Qt.Vertical
+        visible: contentHeight > flickable.height
+        maximumValue: contentHeight > flickable.height ? scrollarea.contentHeight - flickable.height : 0
+        minimumValue: 0
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        anchors.bottomMargin:  { return (frame ? 1 : 0) + (hscrollbar.visible ? __scrollbarExtent : 0) }
+        onValueChanged: contentY = value
+    }
+
+    QStyleBackground {
+        z:2
+        anchors.fill:parent
+        anchors.margins:-2
+        anchors.rightMargin:-4
+        anchors.bottomMargin:-4
+        visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget")
+        style: QStyleItem {
+            id:framestyle
+            elementType:"focusframe"
+        }
+    }
+}
diff --git a/src/widgets/ScrollBar.qml b/src/widgets/ScrollBar.qml
new file mode 100644
index 000000000..ea822b62e
--- /dev/null
+++ b/src/widgets/ScrollBar.qml
@@ -0,0 +1,109 @@
+import QtQuick 1.1
+import "../../../components" as Components
+import "../plugin"
+
+MouseArea {
+    id:scrollbar
+    property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    implicitWidth:orientation == Qt.Horizontal ? 200 : __scrollbarExtent;
+    implicitHeight:orientation == Qt.Horizontal ? __scrollbarExtent : 200
+
+    property int orientation : Qt.Horizontal
+    property alias minimumValue: slider.minimumValue
+    property alias maximumValue: slider.maximumValue
+    property alias value: slider.value
+
+    property bool upPressed;
+    property bool downPressed;
+    property bool __autoincrement: false
+
+    // Update hover item
+    onEntered: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY)
+    onExited: styleitem.activeControl = "none"
+    onMouseXChanged: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY)
+    hoverEnabled:true
+
+    Timer { running: upPressed || downPressed; interval: 350 ; onTriggered: __autoincrement = true }
+    Timer { running: __autoincrement; interval: 60 ; repeat: true ;
+        onTriggered: upPressed ? decrement() : increment() }
+
+    onPressed: {
+        var control = bgitem.hitTest(mouseX,mouseY)
+        if (control == "up") {
+            upPressed = true
+        } else if (control == "down") {
+            downPressed = true
+        }
+    }
+
+    onReleased: {
+        __autoincrement = false;
+        if (upPressed) {
+            upPressed = false;
+            decrement()
+        } else if (downPressed) {
+            increment()
+            downPressed = false;
+        }
+    }
+
+    function increment() {
+        value += 30
+        if (value > maximumValue)
+            value = maximumValue
+    }
+
+    function decrement() {
+        value -= 30
+        if (value < minimumValue)
+            value = minimumValue
+    }
+
+    QStyleBackground {
+        id:bgitem
+        anchors.fill:parent
+        style: QStyleItem {
+            id:styleitem
+            elementType: "scrollbar"
+            hover: activeControl != "none"
+            activeControl: "none"
+            sunken: upPressed | downPressed
+            minimum: slider.minimumValue
+            maximum: slider.maximumValue
+            value: slider.value
+            horizontal: orientation == Qt.Horizontal
+            enabled: parent.enabled
+        }
+    }
+
+    property variant handleRect
+    function updateHandle() {
+        handleRect = bgitem.subControlRect("handle")
+        var grooveRect = bgitem.subControlRect("groove");
+        var extra = 0
+        if (orientation == Qt.Vertical) {
+            slider.anchors.topMargin = grooveRect.y + extra
+            slider.anchors.bottomMargin = height - grooveRect.y - grooveRect.height + extra
+        } else {
+            slider.anchors.leftMargin = grooveRect.x + extra
+            slider.anchors.rightMargin = width - grooveRect.x - grooveRect.width + extra
+        }
+    }
+
+    onValueChanged: updateHandle()
+    onMaximumValueChanged: updateHandle()
+    onMinimumValueChanged: updateHandle()
+    Component.onCompleted: updateHandle()
+    Components.Slider {
+        id:slider
+        anchors.fill:parent
+        orientation:scrollbar.orientation
+        leftMargin: (orientation === Qt.Horizontal) ? handleRect.width/2 : handleRect.height/2
+        rightMargin:leftMargin
+        handle: Item { width:orientation == Qt.Vertical ? handleRect.height : handleRect.width;
+                       height:orientation == Qt.Vertical ? handleRect.width : handleRect.height}
+        groove:null
+        valueIndicator:null
+        inverted:orientation != Qt.Horizontal
+    }
+}
diff --git a/src/widgets/Slider.qml b/src/widgets/Slider.qml
new file mode 100644
index 000000000..c6b9c9151
--- /dev/null
+++ b/src/widgets/Slider.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+// jens: ContainsMouse breaks drag functionality
+
+Components.Slider{
+    id:slider
+    minimumWidth:200
+
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 15).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    height: buttonHeight
+
+    groove: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"slider"
+            sunken: pressed
+            maximum:slider.maximumValue
+            minimum:slider.minimumValue
+            value:slider.value
+            horizontal:slider.orientation == Qt.Horizontal
+            enabled:slider.enabled
+        }
+    }
+
+    handle: null
+    valueIndicator: null
+}
diff --git a/src/widgets/SpinBox.qml b/src/widgets/SpinBox.qml
new file mode 100644
index 000000000..2db428cef
--- /dev/null
+++ b/src/widgets/SpinBox.qml
@@ -0,0 +1,91 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.SpinBox {
+    id:spinbox
+
+    property variant __upRect;
+    property variant __downRect;
+    property int __margin: (height -16)/2
+
+    // Align height with button
+    topMargin:__margin
+    bottomMargin:__margin
+
+    property int buttonHeight: edititem.sizeFromContents(100, 20).height
+    QStyleItem { id:edititem; elementType:"edit" }
+    height: buttonHeight
+    clip:false
+
+    background:
+        Item {
+        anchors.fill: parent
+        property variant __editRect
+
+        Rectangle {
+            id:editBackground
+            x: __editRect.x - 1
+            y: __editRect.y
+            width: __editRect.width
+            height: __editRect.height
+        }
+
+        Item {
+            id:focusFrame
+            anchors.fill: editBackground
+            visible:framestyle.styleHint("focuswidget")
+            QStyleBackground{
+                anchors.margins: -6
+                anchors.leftMargin: -5
+                anchors.fill: parent
+                visible:spinbox.activeFocus
+                style: QStyleItem {
+                    id:framestyle
+                    elementType:"focusframe"
+                }
+            }
+        }
+
+        function updateRect() {
+            __upRect = spinboxbg.subControlRect("up");
+            __downRect = spinboxbg.subControlRect("down");
+            __editRect = spinboxbg.subControlRect("edit");
+        }
+
+        Component.onCompleted:updateRect()
+        onWidthChanged:updateRect()
+        onHeightChanged:updateRect()
+
+        QStyleBackground {
+            id:spinboxbg
+            anchors.fill:parent
+            style: QStyleItem {
+                id: styleitem
+                elementType: "spinbox"
+                sunken: downPressed | upPressed
+                hover: containsMouse
+                focus: spinbox.activeFocus
+                enabled: spinbox.enabled
+                value: (upPressed? 1 : 0)           |
+                        (downPressed== 1 ? 1<<1 : 0) |
+                        (upEnabled? (1<<2) : 0)      |
+                        (downEnabled == 1 ? (1<<3) : 0)
+            }
+        }
+    }
+
+    up: Item {
+        x: __upRect.x
+        y: __upRect.y
+        width: __upRect.width
+        height: __upRect.height
+    }
+
+    down: Item {
+        x: __downRect.x
+        y: __downRect.y
+        width: __downRect.width
+        height: __downRect.height
+    }
+}
diff --git a/src/widgets/Switch.qml b/src/widgets/Switch.qml
new file mode 100644
index 000000000..b82817c9f
--- /dev/null
+++ b/src/widgets/Switch.qml
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Switch {
+    id:widget
+    minimumWidth:100
+    minimumHeight:30
+
+    groove:QStyleItem {
+        elementType:"edit"
+        sunken: true
+    }
+
+    handle: QStyleItem {
+        elementType:"button"
+        width:widget.width/2
+        height:widget.height-4
+        hover:containsMouse
+    }
+}
+
diff --git a/src/widgets/Tab.qml b/src/widgets/Tab.qml
new file mode 100644
index 000000000..e258185ba
--- /dev/null
+++ b/src/widgets/Tab.qml
@@ -0,0 +1,7 @@
+import Qt 4.7
+
+Item {
+    id:tab
+    anchors.fill:parent
+    property string title
+}
diff --git a/src/widgets/TabBar.qml b/src/widgets/TabBar.qml
new file mode 100644
index 000000000..2d891256f
--- /dev/null
+++ b/src/widgets/TabBar.qml
@@ -0,0 +1,90 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+
+Item {
+    id: tabbar
+    property int tabHeight: styleitem.sizeFromContents(100, 24).height
+    height: tabHeight
+
+    property Item tabFrame
+    onTabFrameChanged:parent = tabFrame
+    visible: tabFrame ? tabFrame.tabsVisible : true
+    property int __overlap : styleitem.pixelMetric("tabvshift");
+    property string position: tabFrame ? tabFrame.position : "North"
+    property string tabBarAlignment: styleitem.styleHint("tabbaralignment");
+    property int tabOverlap: styleitem.pixelMetric("taboverlap");
+
+    function tab(index) {
+        for (var i = 0; i < tabrow.children.length; ++i) {
+            if (tabrow.children[i].tabindex == index) {
+                return tabrow.children[i]
+            }
+        }
+        return null;
+    }
+
+    QStyleItem {
+        id:styleitem
+        elementType: "tab"
+        text: "generic"
+    }
+
+    Row {
+        id:tabrow
+        states:
+        State {
+            when: tabBarAlignment == "center"
+            name: "centered"
+            AnchorChanges {
+                target:tabrow
+                anchors.horizontalCenter: tabbar.horizontalCenter
+            }
+        }
+        Repeater {
+            id:repeater
+            model: tabFrame ? tabFrame.tabs.length : null
+            delegate: Item {
+                id:tab
+                property int tabindex: index
+                property bool selected : tabFrame.current == index
+                width: textitem.width + 42
+                height: tabHeight
+                z: selected ? 1 : -1
+
+                QStyleBackground {
+                    style: QStyleItem {
+                        id:style
+                        elementType: "tab"
+                        selected: tab.selected
+                        text: tabbar.position
+
+                        activeControl: tabFrame.count == 1 ?
+                                           "only" :
+                        index == 0 ? "beginning" :
+                            index == tabFrame.count-1 ? "end" : "middle"
+                    }
+                    anchors.leftMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle" || style.activeControl == "end")
+                                        && tab.selected ? -__overlap : 0)
+
+                    anchors.rightMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle"  || style.activeControl == "beginning")
+                                         && tab.selected ? -__overlap : 0)
+                    anchors.fill:parent
+                }
+
+                Text {
+                    id:textitem
+                    anchors.centerIn:parent
+                    text:  tabFrame.tabs[index].title
+                    elide: Text.ElideRight
+                }
+
+                MouseArea {
+                    anchors.fill: parent
+                    onPressed: tabFrame.current = index
+                }
+            }
+        }
+    }
+}
diff --git a/src/widgets/TabFrame.qml b/src/widgets/TabFrame.qml
new file mode 100644
index 000000000..01896e753
--- /dev/null
+++ b/src/widgets/TabFrame.qml
@@ -0,0 +1,72 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Item{
+    id: tabWidget
+    width:100
+    height:100
+    property TabBar tabbar
+    property int current: 0
+    property int count: stack.children.length
+    property bool frame:true
+    property bool tabsVisible: true
+    property string position: "North"
+    default property alias tabs : stack.children
+
+    onCurrentChanged: __setOpacities()
+    Component.onCompleted: __setOpacities()
+    onTabbarChanged: {
+        tabbar.tabFrame = tabWidget
+        tabbar.anchors.top = tabWidget.top
+        tabbar.anchors.left = tabWidget.left
+        tabbar.anchors.right = tabWidget.right
+    }
+
+    property int __baseOverlap : style.pixelMetric("tabbaseoverlap");
+    function __setOpacities() {
+        for (var i = 0; i < stack.children.length; ++i) {
+            stack.children[i].opacity = (i == current ? 1 : 0)
+        }
+    }
+
+    QStyleBackground {
+        id: frame
+        z:-1
+        style: QStyleItem {
+            id:style
+            elementType: "tabframe"
+            text: position
+            value: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).x : 0
+            minimum: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).width : 0
+        }
+        anchors.fill:parent
+        Item {
+            id:stack
+            anchors.fill:parent
+            anchors.margins: frame ? 2 : 0
+        }
+        anchors.topMargin: tabbar && tabsVisible && position == "North" ? tabbar.height - __baseOverlap : 0
+
+        states: [
+            State {
+                name: "South"
+                when: position == "South" && tabbar!= undefined
+                PropertyChanges {
+                    target: frame
+                    anchors.topMargin: 0
+                    anchors.bottomMargin: tabbar ? tabbar.height - __baseOverlap: 0
+                }
+                PropertyChanges {
+                    target: tabbar
+                    anchors.topMargin: -__baseOverlap
+                }
+                AnchorChanges {
+                    target: tabbar
+                    anchors.top: frame.bottom
+                    anchors.bottom: undefined
+                }
+            }
+        ]
+    }
+}
diff --git a/src/widgets/TextArea.qml b/src/widgets/TextArea.qml
new file mode 100644
index 000000000..93ad8f3d9
--- /dev/null
+++ b/src/widgets/TextArea.qml
@@ -0,0 +1,44 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.TextArea {
+    id:textarea
+    leftMargin:12
+    rightMargin:12
+    minimumWidth:200
+    desktopBehavior:true
+    placeholderText:""
+    clip:false
+    // Align with button
+    property int buttonHeight: buttonitem.sizeFromContents(100, 14).height
+    QStyleItem { id:buttonitem; elementType:"button" }
+    minimumHeight: buttonHeight
+
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"edit"
+            sunken:true
+            focus:textarea.activeFocus
+        }
+    }
+
+    Item{
+        id:focusFrame
+        anchors.fill: textarea
+        parent:textarea.parent
+        visible:framestyle.styleHint("focuswidget")
+        QStyleBackground{
+            anchors.margins: -2
+            anchors.rightMargin:-4
+            anchors.bottomMargin:-4
+            anchors.fill: parent
+            visible:textarea.activeFocus
+            style: QStyleItem {
+                id:framestyle
+                elementType:"focusframe"
+            }
+        }
+    }
+}
diff --git a/src/widgets/TextField.qml b/src/widgets/TextField.qml
new file mode 100644
index 000000000..260584e95
--- /dev/null
+++ b/src/widgets/TextField.qml
@@ -0,0 +1,52 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.TextField {
+    id:textfield
+    minimumWidth:200
+    desktopBehavior:true
+    placeholderText:""
+    topMargin:2
+    bottomMargin:2
+    leftMargin:6
+    rightMargin:6
+    width:200
+    height: editItem.sizeFromContents(100, 20).height
+    clip:false
+
+    QStyleItem {
+        id:editItem
+        elementType:"edit"
+        sunken:true
+        focus:textfield.activeFocus
+        hover:containsMouse
+    }
+
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem{
+            elementType:"edit"
+            sunken:true
+            focus:textfield.activeFocus
+        }
+    }
+
+    Item{
+        id:focusFrame
+        anchors.fill: textfield
+        parent:textfield
+        visible:framestyle.styleHint("focuswidget")
+        QStyleBackground{
+            anchors.margins: -2
+            anchors.rightMargin:-4
+            anchors.bottomMargin:-4
+            anchors.fill: parent
+            visible:textfield.activeFocus
+            style: QStyleItem {
+                id:framestyle
+                elementType:"focusframe"
+            }
+        }
+    }
+}
diff --git a/src/widgets/TextScrollArea.qml b/src/widgets/TextScrollArea.qml
new file mode 100644
index 000000000..2a7deab68
--- /dev/null
+++ b/src/widgets/TextScrollArea.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+ScrollArea {
+    id:area
+    color: "white"
+    width: 280
+    height: 120
+    contentWidth: 200
+
+    property alias text: edit.text
+    property alias wrapMode: edit.wrapMode
+    highlightOnFocus: true
+
+    TextEdit {
+        id: edit
+        text: loremIpsum + loremIpsum;
+        wrapMode: TextEdit.WordWrap;
+        width: area.contentWidth
+        selectByMouse:true
+
+        // keep textcursor within scrollarea
+        onCursorRectangleChanged:
+            if (cursorRectangle.y >= area.contentY + area.height - 1.5*cursorRectangle.height)
+                area.contentY = cursorRectangle.y - area.height + 1.5*cursorRectangle.height
+            else if (cursorRectangle.y < area.contentY)
+                area.contentY = cursorRectangle.y
+
+    }
+}
diff --git a/src/widgets/ToolBar.qml b/src/widgets/ToolBar.qml
new file mode 100644
index 000000000..ce61382ee
--- /dev/null
+++ b/src/widgets/ToolBar.qml
@@ -0,0 +1,12 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+QStyleBackground {
+    id:styleitem
+    width:200
+    height:60
+
+    style: QStyleItem{elementType:"toolbar"}
+}
+
diff --git a/src/widgets/ToolButton.qml b/src/widgets/ToolButton.qml
new file mode 100644
index 000000000..98b2dfebf
--- /dev/null
+++ b/src/widgets/ToolButton.qml
@@ -0,0 +1,18 @@
+import QtQuick 1.0
+import "../../../components" as Components
+import "../plugin"
+
+Components.Button {
+    id:button
+    minimumWidth:30
+    background: QStyleBackground {
+        anchors.fill:parent
+        style: QStyleItem {
+            elementType: "toolbutton"
+            on: pressed | checked
+            sunken: pressed
+            raised: containsMouse
+            hover: containsMouse
+        }
+    }
+}
-- 
GitLab