OSDN Git Service

Introduce QML-based welcome screen using desktop components
authorDaniel Molkentin <daniel.molkentin@nokia.com>
Thu, 11 Nov 2010 15:49:17 +0000 (16:49 +0100)
committerEike Ziller <eike.ziller@nokia.com>
Tue, 28 Jun 2011 22:31:47 +0000 (00:31 +0200)
Implements new XML-based format for examples, demos & tutorials

Done-with: Primrose Mbanefo <ext-primrose.mbanefo@nokia.com>
Change-Id: I42c0afdb419cffe5637cd4f298e828d09e0fb15a
Reviewed-on: http://codereview.qt.nokia.com/840
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
150 files changed:
.gitignore
share/qtcreator/static.pro
share/qtcreator/welcomescreen/components/Button.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ButtonRow.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/CheckBox.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ChoiceList.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ContextMenu.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/Dial.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/Frame.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/GroupBox.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/Menu.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/MenuItem.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ProgressBar.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/RadioButton.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ScrollArea.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ScrollBar.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/Slider.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/SpinBox.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/SplitterRow.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/Switch.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/Tab.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/TabBar.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/TabFrame.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/TableColumn.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/TableView.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/TextArea.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/TextField.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ToolBar.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/ToolButton.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/components.pro [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/BasicButton.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/Button.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/ButtonColumn.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/ButtonGroup.js [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/ButtonRow.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/CheckBox.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/ChoiceList.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/GroupBox.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/ProgressBar.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/Slider.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/SpinBox.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/SplitterRow.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/TextField.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/behaviors/ButtonBehavior.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/behaviors/ModalPopupBehavior.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/components.pro [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/private/ChoiceListPopup.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/components/custom/qmldir [new file with mode: 0644]
share/qtcreator/welcomescreen/components/images/folder_new.png [new file with mode: 0644]
share/qtcreator/welcomescreen/components/qmldir [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qdeclarativefolderlistmodel.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qdeclarativefolderlistmodel.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qrangemodel.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qrangemodel.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qrangemodel_p.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qstyleitem.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qstyleitem.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qstyleplugin.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qstyleplugin.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qtmenu.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qtmenu.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qtmenubar.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qtmenubar.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qtmenuitem.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qtmenuitem.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qwheelarea.cpp [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/qwheelarea.h [new file with mode: 0644]
share/qtcreator/welcomescreen/components/styleitem/styleitem.pro [new file with mode: 0644]
share/qtcreator/welcomescreen/develop.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/examples_fallback.xml [new file with mode: 0644]
share/qtcreator/welcomescreen/gettingstarted.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/newssupport.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/qtcreator_tutorials.xml [new file with mode: 0644]
share/qtcreator/welcomescreen/welcomescreen.pro [new file with mode: 0644]
share/qtcreator/welcomescreen/welcomescreen.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/Button.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/ExampleBrowser.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/FeaturedAndNewsListing.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/Feedback.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/HeaderItemView.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/InsetText.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/LineEdit.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/LinksBar.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/NewsListing.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/RatingBar.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/RecentProjects.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/RecentSessions.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/TabWidget.qml [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/img/draw-star.png [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/img/face-star.png [new file with mode: 0644]
share/qtcreator/welcomescreen/widgets/img/lineedit.png [new file with mode: 0644]
share/share.pro
src/app/main.cpp
src/libs/utils/iwelcomepage.h
src/libs/utils/utils-lib.pri
src/plugins/coreplugin/coreplugin.pro
src/plugins/coreplugin/fancytabwidget.cpp
src/plugins/coreplugin/fancytabwidget.h
src/plugins/coreplugin/modemanager.cpp
src/plugins/coreplugin/modemanager.h
src/plugins/coreplugin/multifeedrssmodel.cpp [new file with mode: 0644]
src/plugins/coreplugin/multifeedrssmodel.h [new file with mode: 0644]
src/plugins/coreplugin/networkaccessmanager.cpp [new file with mode: 0644]
src/plugins/coreplugin/networkaccessmanager.h [new file with mode: 0644]
src/plugins/cpaster/protocol.cpp
src/plugins/git/gitorious/gitorious.cpp
src/plugins/help/helpplugin.cpp
src/plugins/help/helpplugin.h
src/plugins/help/helpviewer_qwv.cpp
src/plugins/plugins.pro
src/plugins/projectexplorer/projectexplorer.cpp
src/plugins/projectexplorer/projectexplorer.h
src/plugins/projectexplorer/projectexplorer.pro
src/plugins/projectexplorer/projectwelcomepage.cpp
src/plugins/projectexplorer/projectwelcomepage.h
src/plugins/projectexplorer/projectwelcomepagewidget.h [deleted file]
src/plugins/projectexplorer/projectwelcomepagewidget.ui [deleted file]
src/plugins/qt4projectmanager/gettingstartedwelcomepage.cpp [deleted file]
src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui [deleted file]
src/plugins/qt4projectmanager/qt4projectmanager.pro
src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
src/plugins/qt4projectmanager/qt4projectmanagerplugin.h
src/plugins/qtsupport/exampleslistmodel.cpp [new file with mode: 0644]
src/plugins/qtsupport/exampleslistmodel.h [new file with mode: 0644]
src/plugins/qtsupport/gettingstartedwelcomepage.cpp [new file with mode: 0644]
src/plugins/qtsupport/gettingstartedwelcomepage.h [moved from src/plugins/qt4projectmanager/gettingstartedwelcomepage.h with 69% similarity]
src/plugins/qtsupport/gettingstartedwelcomepagewidget.cpp [moved from src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp with 100% similarity]
src/plugins/qtsupport/gettingstartedwelcomepagewidget.h [moved from src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.h with 100% similarity]
src/plugins/qtsupport/qtsupport.pro
src/plugins/qtsupport/qtsupportplugin.cpp
src/plugins/qtsupport/qtsupportplugin.h
src/plugins/texteditor/generichighlighter/definitiondownloader.cpp
src/plugins/texteditor/generichighlighter/manager.h
src/plugins/welcome/communitywelcomepage.h
src/plugins/welcome/communitywelcomepagewidget.ui [deleted file]
src/plugins/welcome/images/background_center_frame_v1.png [new file with mode: 0644]
src/plugins/welcome/images/background_center_frame_v2.png [new file with mode: 0644]
src/plugins/welcome/images/tab_active.png [new file with mode: 0644]
src/plugins/welcome/images/tab_hover.png [new file with mode: 0644]
src/plugins/welcome/images/tab_inactive.png [new file with mode: 0644]
src/plugins/welcome/welcome.pro
src/plugins/welcome/welcome.qrc
src/plugins/welcome/welcome_dependencies.pri
src/plugins/welcome/welcomemode.ui [deleted file]
src/plugins/welcome/welcomeplugin.cpp
src/tools/examplesscanner/examplesscanner.pro [new file with mode: 0644]
src/tools/examplesscanner/helpextractor.cpp [new file with mode: 0644]
src/tools/examplesscanner/helpextractor.h [new file with mode: 0644]
src/tools/examplesscanner/main.cpp [new file with mode: 0644]

index b5c02f5..4fbf683 100644 (file)
@@ -90,6 +90,7 @@ share/doc/qtcreator/qtcreator.qch
 src/tools/gen-cpp-ast/generate-ast
 src/tools/mkvisitor/cplusplus0
 src/tools/qml/qmldump/qmldump
+src/tools/examplesscanner/examplesscanner
 src/tools/valgrindfake/valgrind-fake
 
 # Tests
index 2c416cd..815d869 100644 (file)
@@ -24,6 +24,7 @@ isEmpty(vcproj) {
 }
 
 DATA_DIRS = \
+    welcomescreen \
     examplebrowser \
     snippets \
     templates \
diff --git a/share/qtcreator/welcomescreen/components/Button.qml b/share/qtcreator/welcomescreen/components/Button.qml
new file mode 100644 (file)
index 0000000..2cc4d43
--- /dev/null
@@ -0,0 +1,63 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.Button {
+    id:button
+
+    // dm: this is wrong
+    width: Math.max(100, button.iconSource !== "" ? labelItem.contentsWidth+12 : 0 )
+    height: Math.max(22, sizehint.height)
+
+    property variant sizehint: backgroundItem.sizeFromContents(80, 6)
+    property bool defaultbutton
+    property string hint
+
+    background: QStyleItem {
+        id: styleitem
+        anchors.fill: parent
+        elementType: "button"
+        sunken: pressed || checked
+        raised: !(pressed || checked)
+        hover: containsMouse
+        text: button.iconSource === "" ? button.text : ""
+        focus: button.focus
+        hint: button.hint
+
+        // If no icon, let the style do the drawing
+        activeControl: focus ? "default" : ""
+        Connections{
+            target: button
+            onToolTipTriggered: styleitem.showTip()
+        }
+        function showTip(){
+            showToolTip(tooltip);
+        }
+    }
+
+    label: Item {
+        // Used as a fallback since I can't pass the imageURL
+        // directly to the style object
+        visible: button.iconSource !== ""
+        property int contentsWidth : row.width
+        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 {
+                id:text
+                color: textColor
+                anchors.verticalCenter: parent.verticalCenter
+                text: button.text
+                horizontalAlignment: Text.Center
+            }
+        }
+    }
+    Keys.onSpacePressed:clicked()
+}
+
diff --git a/share/qtcreator/welcomescreen/components/ButtonRow.qml b/share/qtcreator/welcomescreen/components/ButtonRow.qml
new file mode 100644 (file)
index 0000000..7123b41
--- /dev/null
@@ -0,0 +1,5 @@
+import QtQuick 1.0
+import "custom" as Components
+
+Components.ButtonRow {
+}
diff --git a/share/qtcreator/welcomescreen/components/CheckBox.qml b/share/qtcreator/welcomescreen/components/CheckBox.qml
new file mode 100644 (file)
index 0000000..51055f8
--- /dev/null
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.CheckBox{
+    id:checkbox
+    property string text
+    property string hint
+    height:20
+    width: Math.max(110, backgroundItem.textWidth(text) + 40)
+
+    background: QStyleItem {
+        elementType:"checkbox"
+        sunken:pressed
+        on:checked || pressed
+        hover:containsMouse
+        text:checkbox.text
+        enabled:checkbox.enabled
+        focus:checkbox.focus
+        hint:checkbox.hint
+    }
+    Keys.onSpacePressed:checked = !checked
+}
+
diff --git a/share/qtcreator/welcomescreen/components/ChoiceList.qml b/share/qtcreator/welcomescreen/components/ChoiceList.qml
new file mode 100644 (file)
index 0000000..eb6b5fd
--- /dev/null
@@ -0,0 +1,61 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.ChoiceList {
+
+    id: choicelist
+
+    property int buttonHeight: backgroundItem.sizeFromContents(100, 18).height
+    property int buttonWidth: backgroundItem.sizeFromContents(100, 18).width
+
+    property string hint
+
+    height: buttonHeight
+    width: buttonWidth
+    topMargin: 4
+    bottomMargin: 4
+
+    background: QStyleItem {
+        anchors.fill: parent
+        elementType: "combobox"
+        sunken: pressed
+        raised: !pressed
+        hover: containsMouse
+        enabled: choicelist.enabled
+        text: currentItemText
+        focus: choicelist.focus
+        hint: choicelist.hint
+    }
+
+    listItem: Item {
+        id:item
+
+        height: 22
+        anchors.left: parent.left
+        width: choicelist.width
+        QStyleItem {
+            anchors.fill: parent
+            elementType: "comboboxitem"
+            text: itemText
+            selected: highlighted
+
+        }
+    }
+    popupFrame: QStyleItem {
+        property string popupLocation: backgroundItem.styleHint("comboboxpopup") ? "center" : "below"
+        property int fw: backgroundItem.pixelMetric("menupanelwidth");
+        anchors.leftMargin: backgroundItem.pixelMetric("menuhmargin") + fw
+        anchors.rightMargin: backgroundItem.pixelMetric("menuhmargin") + fw
+        anchors.topMargin: backgroundItem.pixelMetric("menuvmargin") + fw
+        anchors.bottomMargin: backgroundItem.pixelMetric("menuvmargin") + fw
+        elementType: "menu"
+
+        effect: DropShadow {
+            blurRadius: 18
+            color: "#90000000"
+            xOffset: 1
+            yOffset: 1
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/ContextMenu.qml b/share/qtcreator/welcomescreen/components/ContextMenu.qml
new file mode 100644 (file)
index 0000000..14fbc8d
--- /dev/null
@@ -0,0 +1,8 @@
+import QtQuick 1.0
+import "custom" as Components
+
+MenuBase {
+    id: choiceList
+
+    property ListModel model
+}
diff --git a/share/qtcreator/welcomescreen/components/Dial.qml b/share/qtcreator/welcomescreen/components/Dial.qml
new file mode 100644 (file)
index 0000000..e1b367b
--- /dev/null
@@ -0,0 +1,113 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+// jens: ContainsMouse breaks drag functionality
+
+QStyleItem {
+    id: dial
+
+    width:100
+    height:100
+
+    property alias maximumValue: range.maximumValue
+    property alias minimumValue: range.minimumValue
+    property alias containsMouse: mouseArea.containsMouse
+    property alias value: range.value
+
+    property bool wrapping: false
+    property bool tickmarks: true // not implemented
+
+    RangeModel {
+        id: range
+        minimumValue: 0.0
+        maximumValue: 1.0
+        stepSize: 0.0
+        value: 0
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill:parent
+        property bool inDrag
+        hoverEnabled:true
+
+        onPositionChanged: {
+            if (pressed) {
+                value = valueFromPoint(mouseX, mouseY)
+                inDrag = true
+            }
+        }
+        onPressed: {
+            value = valueFromPoint(mouseX, mouseY)
+            dial.focus = true
+        }
+
+        onReleased:inDrag = false;
+        function bound(val) { return Math.max(minimumValue, Math.min(maximumValue, val)); }
+
+        function valueFromPoint(x, y)
+        {
+            var yy = height/2.0 - y;
+            var xx = x - width/2.0;
+            var a = (xx || yy) ? Math.atan2(yy, xx) : 0;
+
+            if (a < Math.PI/ -2)
+                a = a + Math.PI * 2;
+
+            var dist = 0;
+            var minv = minimumValue*100, maxv = maximumValue*100;
+
+            if (minimumValue < 0) {
+                dist = -minimumValue;
+                minv = 0;
+                maxv = maximumValue + dist;
+            }
+
+            var r = maxv - minv;
+            var v;
+            if (wrapping)
+                v =  (0.5 + minv + r * (Math.PI * 3 / 2 - a) / (2 * Math.PI));
+            else
+                v =  (0.5 + minv + r* (Math.PI * 4 / 3 - a) / (Math.PI * 10 / 6));
+
+            if (dist > 0)
+                v -= dist;
+            return maximumValue - bound(v/100)
+        }
+    }
+
+    WheelArea {
+        id: wheelarea
+        anchors.fill: parent
+        horizontalMinimumValue: dial.minimumValue
+        horizontalMaximumValue: dial.maximumValue
+        verticalMinimumValue: dial.minimumValue
+        verticalMaximumValue: dial.maximumValue
+        property double step: (dial.maximumValue - dial.minimumValue)/100
+
+        onVerticalWheelMoved: {
+            value += verticalDelta/4*step
+        }
+
+        onHorizontalWheelMoved: {
+            value += horizontalDelta/4*step
+        }
+    }
+
+    elementType:"dial"
+    sunken: mouseArea.pressed
+    maximum: range.maximumValue*90
+    minimum: range.minimumValue*90
+    focus:dial.focus
+    value: visualPos*90
+    enabled: dial.enabled
+    property double visualPos : range.value
+    Behavior on visualPos {
+        enabled: !mouseArea.inDrag
+        NumberAnimation {
+            duration: 300
+            easing.type: Easing.OutSine
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/Frame.qml b/share/qtcreator/welcomescreen/components/Frame.qml
new file mode 100644 (file)
index 0000000..24a8e83
--- /dev/null
@@ -0,0 +1,25 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+
+QStyleBackground {
+
+    width: 100
+    height: 100
+
+    default property alias children: content.children
+
+    style: QStyleItem {
+        id: styleitem
+        elementType: "frame"
+    }
+
+    Item {
+        id: content
+        anchors.fill: parent
+        anchors.margins: frameWidth
+        property int frameWidth: styleitem.pixelMetric("defaultframewidth");
+    }
+}
+
diff --git a/share/qtcreator/welcomescreen/components/GroupBox.qml b/share/qtcreator/welcomescreen/components/GroupBox.qml
new file mode 100644 (file)
index 0000000..d2184d5
--- /dev/null
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.GroupBox {
+    id: groupbox
+    width: Math.max(200, contentWidth + sizeHint.width)
+    height: contentHeight + sizeHint.height + 4
+    property variant sizeHint: backgroundItem.sizeFromContents(0, 24)
+    property bool flat: false
+    background : QStyleItem {
+        id: styleitem
+        elementType: "groupbox"
+        anchors.fill: parent
+        text: groupbox.title
+        hover: checkbox.containsMouse
+        on: checkbox.checked
+        focus: checkbox.activeFocus
+        activeControl: checkable ? "checkbox" : ""
+        sunken: !flat
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/Menu.qml b/share/qtcreator/welcomescreen/components/Menu.qml
new file mode 100644 (file)
index 0000000..000219e
--- /dev/null
@@ -0,0 +1,6 @@
+import QtQuick 1.0
+import "../components/plugin"
+
+MenuBase {
+
+}
diff --git a/share/qtcreator/welcomescreen/components/MenuItem.qml b/share/qtcreator/welcomescreen/components/MenuItem.qml
new file mode 100644 (file)
index 0000000..52a0511
--- /dev/null
@@ -0,0 +1,6 @@
+import QtQuick 1.0
+import "../components/plugin"
+
+MenuItemBase {
+
+}
diff --git a/share/qtcreator/welcomescreen/components/ProgressBar.qml b/share/qtcreator/welcomescreen/components/ProgressBar.qml
new file mode 100644 (file)
index 0000000..9b2d368
--- /dev/null
@@ -0,0 +1,29 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.ProgressBar {
+    id:progressbar
+
+    property variant sizehint: backgroundItem.sizeFromContents(23, 23)
+    property int orientation: Qt.Horizontal
+    property string hint
+
+    height: orientation === Qt.Horizontal ? sizehint.height : 200
+    width: orientation === Qt.Horizontal ? 200 : sizehint.height
+
+    background: QStyleItem {
+        anchors.fill: parent
+        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 : 1000
+        value:   indeterminate ? 0 : progressbar.value * factor // does indeterminate value need to be 1 on windows?
+        minimum: indeterminate ? 0 : progressbar.minimumValue * factor
+        maximum: indeterminate ? 0 : progressbar.maximumValue * factor
+        enabled: progressbar.enabled
+        horizontal: progressbar.orientation == Qt.Horizontal
+        hint: progressbar.hint
+    }
+}
+
diff --git a/share/qtcreator/welcomescreen/components/RadioButton.qml b/share/qtcreator/welcomescreen/components/RadioButton.qml
new file mode 100644 (file)
index 0000000..cfc16c9
--- /dev/null
@@ -0,0 +1,26 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+// jb : Size should not depend on background, we should make it consistent
+
+Components.CheckBox {
+    id:radiobutton
+    property string text
+    property string hint
+    width:110
+    height:20
+
+    background: QStyleItem {
+        elementType:"radiobutton"
+        sunken:pressed
+        on:checked || pressed
+        hover:containsMouse
+        text:radiobutton.text
+        enabled:radiobutton.enabled
+        focus:radiobutton.focus
+        hint:radiobutton.hint
+    }
+    Keys.onSpacePressed:clicked()
+}
+
diff --git a/share/qtcreator/welcomescreen/components/ScrollArea.qml b/share/qtcreator/welcomescreen/components/ScrollArea.qml
new file mode 100644 (file)
index 0000000..4c79a09
--- /dev/null
@@ -0,0 +1,140 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+FocusScope {
+    id: scrollarea
+    width: 100
+    height: 100
+
+    property int frameWidth: frame ? styleitem.pixelMetric("defaultframewidth") : 0;
+    property int contentHeight : content.childrenRect.height
+    property int contentWidth: content.childrenRect.width
+    property alias color: colorRect.color
+    property bool frame: true
+    property bool highlightOnFocus: false
+    property bool frameAroundContents: styleitem.styleHint("framearoundcontents")
+    property alias verticalValue: vscrollbar.value
+    property alias horizontalValue: hscrollbar.value
+
+    default property alias data: content.data
+
+    property int contentY
+    property int contentX
+
+    onContentYChanged: {
+        vscrollbar.value = contentY
+        wheelarea.verticalValue = contentY
+    }
+    onContentXChanged: {
+        hscrollbar.value = contentX
+        wheelarea.horizontalValue = contentX
+    }
+
+    Rectangle {
+        id: colorRect
+        color: "transparent"
+        anchors.fill:styleitem
+        anchors.margins: frameWidth
+    }
+
+    QStyleItem {
+        id: styleitem
+        elementType: "frame"
+        onElementTypeChanged: scrollarea.frameWidth = styleitem.pixelMetric("defaultframewidth");
+        sunken: true
+        visible: frame
+        anchors.fill: parent
+        anchors.rightMargin: frame ? (frameAroundContents ? (vscrollbar.visible ? vscrollbar.width + 2 * frameMargins : 0) : -frameWidth) : 0
+        anchors.bottomMargin: frame ? (frameAroundContents ? (hscrollbar.visible ? hscrollbar.height + 2 * frameMargins : 0) : -frameWidth) : 0
+        anchors.topMargin: frame ? (frameAroundContents ? 0 : -frameWidth) : 0
+        property int scrollbarspacing: styleitem.pixelMetric("scrollbarspacing");
+        property int frameMargins : frame ? scrollbarspacing : 0
+        property int frameoffset: style === "mac" ? -1 : 0
+    }
+
+    Item {
+        id: flickable
+        anchors.fill: styleitem
+        anchors.margins: frameWidth
+        clip: true
+
+        Item {
+            id: content
+            x: -scrollarea.contentX
+            y: -scrollarea.contentY
+        }
+    }
+
+    WheelArea {
+        id: wheelarea
+        anchors.fill: parent
+        horizontalMinimumValue: hscrollbar.minimumValue
+        horizontalMaximumValue: hscrollbar.maximumValue
+        verticalMinimumValue: vscrollbar.minimumValue
+        verticalMaximumValue: vscrollbar.maximumValue
+
+        onVerticalValueChanged: {
+            contentY = verticalValue
+        }
+
+        onHorizontalValueChanged: {
+            contentX = horizontalValue
+        }
+    }
+
+    ScrollBar {
+        id: hscrollbar
+        orientation: Qt.Horizontal
+        property int availableWidth : scrollarea.width - (frame ? (vscrollbar.width) : 0)
+        visible: contentWidth > availableWidth
+        maximumValue: contentWidth > availableWidth ? scrollarea.contentWidth - availableWidth: 0
+        minimumValue: 0
+        anchors.bottom: parent.bottom
+        anchors.bottomMargin: styleitem.frameoffset
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.leftMargin: (frame ? frameWidth : 0)
+        anchors.rightMargin: { vscrollbar.visible ? scrollbarExtent : (frame ? 1 : 0) }
+        onValueChanged: contentX = value
+        property int scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    }
+
+    ScrollBar {
+        id: vscrollbar
+        orientation: Qt.Vertical
+        property int availableHeight : scrollarea.height - (frame ? (hscrollbar.height) : 0)
+        visible: contentHeight > availableHeight
+        maximumValue: contentHeight > availableHeight ? scrollarea.contentHeight - availableHeight : 0
+        minimumValue: 0
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        anchors.topMargin: styleitem.style == "mac" ? 1 : 0
+        onValueChanged: contentY = value
+        anchors.rightMargin: styleitem.frameoffset
+        anchors.bottomMargin: hscrollbar.visible ? hscrollbar.height : styleitem.frameoffset
+    }
+
+    Rectangle {
+        // This is the filled corner between scrollbars
+        id: cornerFill
+        anchors.left:  vscrollbar.left
+        anchors.right: vscrollbar.right
+        anchors.top: hscrollbar.top
+        anchors.bottom: hscrollbar.bottom
+        visible: hscrollbar.visible && vscrollbar.visible
+        SystemPalette { id: syspal }
+        color: syspal.window
+    }
+
+    QStyleItem {
+        z: 2
+        anchors.fill: parent
+        anchors.margins: -3
+        anchors.rightMargin: -4
+        anchors.bottomMargin: -4
+        visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget")
+        elementType: "focusframe"
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/ScrollBar.qml b/share/qtcreator/welcomescreen/components/ScrollBar.qml
new file mode 100644 (file)
index 0000000..ef1a937
--- /dev/null
@@ -0,0 +1,127 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Item {
+    id: scrollbar
+
+    property bool upPressed
+    property bool downPressed
+    property int orientation : Qt.Horizontal
+    property alias minimumValue: slider.minimumValue
+    property alias maximumValue: slider.maximumValue
+    property alias value: slider.value
+
+    width: orientation == Qt.Horizontal ? 200 : internal.scrollbarExtent
+    height: orientation == Qt.Horizontal ? internal.scrollbarExtent : 200
+
+    onValueChanged: internal.updateHandle()
+    // onMaximumValueChanged: internal.updateHandle()
+    // onMinimumValueChanged: internal.updateHandle()
+
+    MouseArea {
+        id: internal
+
+        anchors.fill: parent
+
+        property bool autoincrement: false
+        property int scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+
+        // Update hover item
+        onEntered: styleitem.activeControl = styleitem.hitTest(mouseX, mouseY)
+        onExited: styleitem.activeControl = "none"
+        onMouseXChanged: styleitem.activeControl = styleitem.hitTest(mouseX, mouseY)
+        hoverEnabled: true
+
+        Timer {
+            running: upPressed || downPressed
+            interval: 350
+            onTriggered: internal.autoincrement = true
+        }
+
+        Timer {
+            running: internal.autoincrement
+            interval: 60
+            repeat: true
+            onTriggered: upPressed ? internal.decrement() : internal.increment()
+        }
+
+        onPressed: {
+            var control = styleitem.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
+        }
+
+        QStyleItem {
+            id: styleitem
+            anchors.fill:parent
+            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: Qt.rect(0,0,0,0)
+        function updateHandle() {
+            internal.handleRect = styleitem.subControlRect("handle")
+            var grooveRect = styleitem.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
+            }
+        }
+
+
+        Components.Slider {
+            id: slider
+            hoverEnabled: false // Handled by the scrollbar background
+            orientation: scrollbar.orientation
+            anchors.fill: parent
+            leftMargin: (orientation === Qt.Horizontal) ? internal.handleRect.width / 2 : internal.handleRect.height / 2
+            rightMargin: leftMargin
+            handle: Item {
+                width: orientation == Qt.Vertical ? internal.handleRect.height : internal.handleRect.width;
+                height: orientation == Qt.Vertical ? internal.handleRect.width : internal.handleRect.height
+            }
+            groove:null
+            containsMouse: false
+            valueIndicator:null
+            inverted:orientation != Qt.Horizontal
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/Slider.qml b/share/qtcreator/welcomescreen/components/Slider.qml
new file mode 100644 (file)
index 0000000..b872035
--- /dev/null
@@ -0,0 +1,60 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+// jens: ContainsMouse breaks drag functionality
+
+Components.Slider{
+    id: slider
+
+    property bool tickmarksEnabled: true
+    property string tickPosition: "Below" // "Top", "Below", "BothSides"
+
+    QStyleItem { id:buttonitem; elementType: "slider" }
+
+    property variant sizehint: buttonitem.sizeFromContents(23, 23)
+    property int orientation: Qt.Horizontal
+
+    height: orientation === Qt.Horizontal ? sizehint.height : 200
+    width: orientation === Qt.Horizontal ? 200 : sizehint.height
+    property string hint;
+
+    groove: QStyleItem {
+        anchors.fill:parent
+        elementType: "slider"
+        sunken: pressed
+        maximum: slider.maximumValue*100
+        minimum: slider.minimumValue*100
+        value: slider.value*100
+        horizontal: slider.orientation == Qt.Horizontal
+        enabled: slider.enabled
+        focus: slider.focus
+        hint: slider.hint
+        activeControl: tickmarksEnabled ? tickPosition.toLowerCase() : ""
+    }
+
+    handle: null
+    valueIndicator: null
+
+    Keys.onRightPressed: value += (maximumValue - minimumValue)/10.0
+    Keys.onLeftPressed: value -= (maximumValue - minimumValue)/10.0
+
+    WheelArea {
+        id: wheelarea
+        anchors.fill: parent
+        horizontalMinimumValue: slider.minimumValue
+        horizontalMaximumValue: slider.maximumValue
+        verticalMinimumValue: slider.minimumValue
+        verticalMaximumValue: slider.maximumValue
+        property double step: (slider.maximumValue - slider.minimumValue)/100
+
+        onVerticalWheelMoved: {
+            value += verticalDelta/4*step
+        }
+
+        onHorizontalWheelMoved: {
+            value += horizontalDelta/4*step
+        }
+    }
+
+}
diff --git a/share/qtcreator/welcomescreen/components/SpinBox.qml b/share/qtcreator/welcomescreen/components/SpinBox.qml
new file mode 100644 (file)
index 0000000..919ac95
--- /dev/null
@@ -0,0 +1,96 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.SpinBox {
+    id:spinbox
+
+    property variant __upRect;
+    property variant __downRect;
+    property int __margin: (height -16)/2
+    property string hint
+
+    // Align height with button
+    topMargin:__margin
+    bottomMargin:__margin
+
+    leftMargin:6
+    rightMargin:6
+
+    QStyleItem { id:edititem ; elementType:"edit" ; visible:false }
+    property int buttonHeight:  edititem.sizeFromContents(70, 20).height
+    property int buttonWidth: edititem.sizeFromContents(70, 20).width
+
+    height: buttonHeight
+    width: buttonWidth
+    clip:false
+
+    background: Item {
+        anchors.fill: parent
+        property variant __editRect
+
+        Rectangle {
+            id: editBackground
+            x: __editRect.x - 1
+            y: __editRect.y
+            width: __editRect.width + 1
+            height: __editRect.height
+        }
+
+        Item {
+            id: focusFrame
+            anchors.fill: editBackground
+            visible: frameitem.styleHint("focuswidget")
+            QStyleItem {
+                id: frameitem
+                anchors.margins: -6
+                anchors.leftMargin: -6
+                anchors.rightMargin: -7
+                anchors.fill: parent
+                visible: spinbox.activeFocus
+                elementType: "focusframe"
+            }
+        }
+
+        function updateRect() {
+            __upRect = styleitem.subControlRect("up");
+            __downRect = styleitem.subControlRect("down");
+            __editRect = styleitem.subControlRect("edit");
+            spinbox.leftMargin = __editRect.x + 2
+            spinbox.rightMargin = spinbox.width -__editRect.width - __editRect.x
+        }
+
+        Component.onCompleted: updateRect()
+        onWidthChanged: updateRect()
+        onHeightChanged: updateRect()
+
+        QStyleItem {
+            id: styleitem
+            anchors.fill: parent
+            elementType: "spinbox"
+            sunken: (downEnabled && downPressed) | (upEnabled && upPressed)
+            hover: containsMouse
+            focus: spinbox.focus
+            enabled: spinbox.enabled
+            value: (upPressed ? 1 : 0)           |
+                   (downPressed == 1 ? 1<<1 : 0) |
+                   (upEnabled ? (1<<2) : 0)      |
+                   (downEnabled == 1 ? (1<<3) : 0)
+            hint: spinbox.hint
+        }
+    }
+
+    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/share/qtcreator/welcomescreen/components/SplitterRow.qml b/share/qtcreator/welcomescreen/components/SplitterRow.qml
new file mode 100644 (file)
index 0000000..adcc535
--- /dev/null
@@ -0,0 +1,25 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.SplitterRow {
+    handleBackground: QStyleItem {
+            id: styleitem
+            elementType: "splitter"
+            width: pixelMetric("splitterwidth")
+
+            MouseArea {
+                anchors.fill: parent
+                anchors.leftMargin: (parent.width <= 1) ? -2 : 0
+                anchors.rightMargin: (parent.width <= 1) ? -2 : 0
+                drag.axis: Qt.YAxis
+                drag.target: handleDragTarget
+                onMouseXChanged: handleDragged(handleIndex)
+
+                QStyleItem {
+                    anchors.fill: parent
+                    cursor: "splithcursor"
+                }
+            }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/Switch.qml b/share/qtcreator/welcomescreen/components/Switch.qml
new file mode 100644 (file)
index 0000000..5d661ec
--- /dev/null
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "custom" 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/share/qtcreator/welcomescreen/components/Tab.qml b/share/qtcreator/welcomescreen/components/Tab.qml
new file mode 100644 (file)
index 0000000..b0e223d
--- /dev/null
@@ -0,0 +1,8 @@
+import Qt 4.7
+
+Item {
+    id:tab
+    anchors.fill: parent
+    property string title
+    property int contentMargin
+}
diff --git a/share/qtcreator/welcomescreen/components/TabBar.qml b/share/qtcreator/welcomescreen/components/TabBar.qml
new file mode 100644 (file)
index 0000000..b5869eb
--- /dev/null
@@ -0,0 +1,111 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+
+Item {
+    id: tabbar
+    property int tabHeight: tabrow.height
+    property int tabWidth: tabrow.width
+
+    Keys.onRightPressed: {
+        if (tabFrame && tabFrame.current < tabFrame.count - 1)
+            tabFrame.current = tabFrame.current + 1
+    }
+    Keys.onLeftPressed: {
+        if (tabFrame && tabFrame.current > 0)
+            tabFrame.current = tabFrame.current - 1
+    }
+
+    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");
+    property int tabBaseOverlap: styleitem.pixelMetric("tabbaseoverlap");
+    property int tabHSpace: styleitem.pixelMetric("tabhspace");
+    property int tabVSpace: styleitem.pixelMetric("tabvspace");
+
+    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 {
+        visible:false
+        id:styleitem
+        elementType: "tab"
+        text: "generic"
+    }
+
+    Row {
+        id: tabrow
+        focus: true
+        property int paintMargins: 1
+        states:
+                State {
+            when: tabBarAlignment == "center"
+            name: "centered"
+            AnchorChanges {
+                target:tabrow
+                anchors.horizontalCenter: tabbar.horizontalCenter
+            }
+        }
+
+        Repeater {
+            id:repeater
+            focus:true
+            model: tabFrame ? tabFrame.tabs.length : null
+            delegate: Item {
+                id:tab
+                focus:true
+                property int tabindex: index
+                property bool selected : tabFrame.current == index
+                z: selected ? 1 : -1
+                function updateRect() {
+                    var rect = style.sizeFromContents(textitem.width + tabHSpace + 2, Math.max(style.fontHeight + tabVSpace + 6, 0))
+                    width = rect.width
+                    height = rect.height
+                }
+                // Component.onCompleted: print("taboverlap" + tabOverlap + " tabbaseoverlap " + tabBaseOverlap + " overlap " +__overlap + " hspace " + tabHSpace)
+                QStyleItem {
+                    id: style
+                    elementType: "tab"
+                    selected: tab.selected
+                    info: tabbar.position
+                    text: tabFrame.tabs[index].title
+                    hover: mousearea.containsMouse
+                    focus: tabbar.focus && selected
+                    property bool first: index === 0
+                    paintMargins: tabrow.paintMargins
+                    activeControl: tabFrame.count == 1 ? "only" : index === 0 ? "beginning" :
+                            index == tabFrame.count-1 ? "end" : "middle"
+                    anchors.fill: parent
+                    anchors.margins: -paintMargins
+                    Text {
+                        id: textitem
+                        // Used for size hint
+                        visible: false
+                        onWidthChanged: updateRect()
+                        onHeightChanged: updateRect()
+                        text: tabFrame.tabs[index].title
+                    }
+                }
+                MouseArea {
+                    id: mousearea
+                    anchors.fill: parent
+                    hoverEnabled: true
+                    onPressed: tabFrame.current = index
+                }
+            }
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/TabFrame.qml b/share/qtcreator/welcomescreen/components/TabFrame.qml
new file mode 100644 (file)
index 0000000..10d63db
--- /dev/null
@@ -0,0 +1,77 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Item {
+    id: tabWidget
+    width: 100
+    height: 100
+    focus: true
+    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 : frameitem.pixelMetric("tabbaseoverlap")// add paintmargins;
+    function __setOpacities() {
+        for (var i = 0; i < stack.children.length; ++i) {
+            stack.children[i].visible = (i == current ? true : false)
+        }
+    }
+
+    QStyleItem {
+        id: frameitem
+        z: style == "oxygen" ? 1 : 0
+        elementType: "tabframe"
+        info: position
+        value: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).x : 0
+        minimum: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).width : 0
+        maximum: tabbar && tabsVisible ? tabbar.tabWidth : width
+        anchors.fill: parent
+
+        property int frameWidth: pixelMetric("defaultframewidth")
+
+        Item {
+            id: stack
+            anchors.fill: parent
+            anchors.margins: (frame ? frameitem.frameWidth : 0)
+            anchors.topMargin: anchors.margins + (frameitem.style =="mac" ? 6 : 0)
+            anchors.bottomMargin: anchors.margins + (frameitem.style =="mac" ? 6 : 0)
+        }
+
+        anchors.topMargin: tabbar && tabsVisible && position == "North" ? tabbar.height - __baseOverlap : 0
+
+        states: [
+            State {
+                name: "South"
+                when: position == "South" && tabbar!= undefined
+                PropertyChanges {
+                    target: frameitem
+                    anchors.topMargin: 0
+                    anchors.bottomMargin: tabbar ? tabbar.height - __baseOverlap: 0
+                }
+                PropertyChanges {
+                    target: tabbar
+                    anchors.topMargin: -__baseOverlap
+                }
+                AnchorChanges {
+                    target: tabbar
+                    anchors.top: frameitem.bottom
+                    anchors.bottom: undefined
+                }
+            }
+        ]
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/TableColumn.qml b/share/qtcreator/welcomescreen/components/TableColumn.qml
new file mode 100644 (file)
index 0000000..b40334b
--- /dev/null
@@ -0,0 +1,9 @@
+import QtQuick 1.0
+
+QtObject {
+    property string caption
+    property string property
+    property int width: 160
+    property bool visible: true
+    property int elideMode: Text.ElideRight
+}
diff --git a/share/qtcreator/welcomescreen/components/TableView.qml b/share/qtcreator/welcomescreen/components/TableView.qml
new file mode 100644 (file)
index 0000000..196a0ed
--- /dev/null
@@ -0,0 +1,574 @@
+import QtQuick 1.0
+import "../components"
+import "../components/plugin"
+
+/*
+*
+* TableView
+*
+* This component provides an item-view with resizable
+* header sections.
+*
+* You can style the drawn delegate by overriding the itemDelegate
+* property. The following properties are supported for custom
+* delegates:
+*
+* Note: Currently only row selection is available for this component
+*
+* itemheight - default platform size of item
+* itemwidth - default platform width of item
+* itemselected - if the row is currently selected
+* itemvalue - The text for this item
+* itemforeground - The default text color for an item
+*
+* For example:
+*   itemDelegate: Item {
+*       Text {
+*           anchors.verticalCenter: parent.verticalCenter
+*           color: itemForeground
+*           elide: Text.ElideRight
+*           text: itemValue
+*        }
+*    }
+*
+* Data for each row is provided through a model:
+*
+* ListModel {
+*    ListElement{ column1: "value 1"; column2: "value 2"}
+*    ListElement{ column1: "value 3"; column2: "value 4"}
+* }
+*
+* You provide title and size properties on TableColumns
+* by setting the default header property :
+*
+* TableView {
+*    TableColumn{ property: "column1" ; caption: "Column 1" ; width:100}
+*    TableColumn{ property: "column2" ; caption: "Column 2" ; width:200}
+*    model: datamodel
+* }
+*
+* The header sections are attached to values in the datamodel by defining
+* the listmodel property they attach to. Each property in the model, will
+* then be shown in each column section.
+*
+* The view itself does not provide sorting. This has to
+* be done on the model itself. However you can provide sorting
+* on the model and enable sort indicators on headers.
+*
+* sortColumn - The index of the currently selected sort header
+* sortIndicatorVisible - If sort indicators should be enabled
+* sortIndicatorDirection - "up" or "down" depending on state
+*
+*/
+
+FocusScope{
+    id: root
+    property variant model
+    property int frameWidth: frame ? styleitem.pixelMetric("defaultframewidth") : 0;
+    property alias contentHeight : tree.contentHeight
+    property alias contentWidth: tree.contentWidth
+    property bool frame: true
+    property bool highlightOnFocus: false
+    property bool frameAroundContents: styleitem.styleHint("framearoundcontents")
+    property int sortColumn // Index of currently selected sort column
+
+    property bool sortIndicatorVisible: false // enables or disables sort indicator
+    property string sortIndicatorDirection: "down" // "up" or "down" depending on current state
+
+    property bool alternateRowColor: true
+    property alias contentX: tree.contentX
+    property alias contentY: tree.contentY
+
+    property alias currentIndex: tree.currentIndex // Should this be currentRowIndex?
+
+    property int headerHeight: headerrow.height
+
+    property Component itemDelegate: standardDelegate
+    property Component rowDelegate: rowDelegate
+    property Component headerDelegate: headerDelegate
+    property alias cacheBuffer: tree.cacheBuffer
+
+    property bool headerVisible: true
+
+    default property alias header: tree.header
+
+    signal activated
+
+    Component {
+        id: standardDelegate
+        Item {
+            property int implicitWidth: sizehint.paintedWidth + 4
+            Text {
+                width: parent.width
+                anchors.margins: 4
+                anchors.left: parent.left
+                anchors.verticalCenter: parent.verticalCenter
+                elide: itemElideMode
+                text: itemValue ? itemValue : ""
+                color: itemForeground
+            }
+            Text {
+                id: sizehint
+                text: itemValue ? itemValue : ""
+                visible:false
+            }
+        }
+    }
+
+    Component {
+        id: nativeDelegate
+        // This gives more native styling, but might be less performant
+        QStyleItem {
+            elementType: "item"
+            text:   itemValue
+            selected: itemSelected
+        }
+    }
+
+    Component {
+        id: headerDelegate
+        QStyleItem {
+            elementType: "header"
+            activeControl: itemSort
+            raised: true
+            sunken: itemPressed
+            text: itemValue
+            hover: itemContainsMouse
+        }
+    }
+
+    Component {
+        id: rowDelegate
+        QStyleItem {
+            id: rowstyle
+            elementType: "itemrow"
+            activeControl: itemAlternateBackground ? "alternate" : ""
+            selected: itemSelected ? "true" : "false"
+        }
+    }
+
+    Rectangle {
+        id: colorRect
+        color: "white"
+        anchors.fill: frameitem
+        anchors.margins: frameWidth
+        anchors.rightMargin: (!frameAroundContents && vscrollbar.visible ? vscrollbar.width : 0) + frameWidth
+        anchors.bottomMargin: (!frameAroundContents && hscrollbar.visible ? hscrollbar.height : 0) +frameWidth
+    }
+
+    QStyleItem {
+        id: frameitem
+        elementType: "frame"
+        onElementTypeChanged: scrollarea.frameWidth = styleitem.pixelMetric("defaultframewidth");
+        sunken: true
+        visible: frame
+        anchors.fill: parent
+        anchors.rightMargin: frame ? (frameAroundContents ? (vscrollbar.visible ? vscrollbar.width + 2 * frameMargins : 0) : -frameWidth) : 0
+        anchors.bottomMargin: frame ? (frameAroundContents ? (hscrollbar.visible ? hscrollbar.height + 2 * frameMargins : 0) : -frameWidth) : 0
+        anchors.topMargin: frame ? (frameAroundContents ? 0 : -frameWidth) : 0
+        property int scrollbarspacing: styleitem.pixelMetric("scrollbarspacing");
+        property int frameMargins : frame ? scrollbarspacing : 0
+    }
+    MouseArea {
+        id: mousearea
+
+        anchors.fill: tree
+
+        property bool autoincrement: false
+        property bool autodecrement: false
+
+        onReleased: {
+            autoincrement = false
+            autodecrement = false
+        }
+
+        // Handle vertical scrolling whem dragging mouse outside boundraries
+
+        Timer { running: mousearea.autoincrement; repeat: true; interval: 30 ; onTriggered: tree.incrementCurrentIndex()}
+        Timer { running: mousearea.autodecrement; repeat: true; interval: 30 ; onTriggered: tree.decrementCurrentIndex()}
+
+        onMousePositionChanged: {
+            if (mouseY > tree.height) {
+                autodecrement = false
+                autoincrement = true
+            } else if (mouseY < 0) {
+                autoincrement = false
+                autodecrement = true
+            } else  {
+                autoincrement = false
+                autodecrement = false
+            }
+
+            var y = Math.min(contentY + tree.height - 5, Math.max(mouseY + contentY, contentY))
+
+            var newIndex = tree.indexAt(0, y)
+            if (newIndex > 0)
+                tree.currentIndex = tree.indexAt(0, y)
+        }
+        onPressed:  {
+            tree.forceActiveFocus()
+            var x = Math.min(contentWidth - 5, Math.max(mouseX + contentX, 0))
+            var y = Math.min(contentHeight - 5, Math.max(mouseY + contentY, 0))
+            tree.currentIndex = tree.indexAt(x, y)
+        }
+
+        onDoubleClicked: {
+            parent.activated()
+        }
+    }
+
+    ListView {
+        id: tree
+        property list<TableColumn> header
+        property bool blockUpdates: false
+        highlightFollowsCurrentItem: true
+        model: root.model
+
+        interactive: false
+        anchors.top: tableColumn.bottom
+        anchors.topMargin: -frameWidth
+        anchors.left: frameitem.left
+        anchors.right: frameitem.right
+        anchors.bottom: frameitem.bottom
+        anchors.margins: frameWidth
+
+        anchors.rightMargin: (!frameAroundContents && vscrollbar.visible ? vscrollbar.width: 0) + frameWidth
+        anchors.bottomMargin: (!frameAroundContents && hscrollbar.visible ? hscrollbar.height : 0)  + frameWidth
+
+        focus: true
+        clip: true
+
+        Keys.onUpPressed: {
+            blockUpdates = true
+            if (currentIndex > 0) currentIndex = currentIndex - 1
+            wheelarea.verticalValue = contentY/wheelarea.scale
+            blockUpdates = false
+        }
+        Keys.onDownPressed: {
+            blockUpdates = true
+            if (currentIndex< count - 1) currentIndex = currentIndex + 1
+            wheelarea.verticalValue = contentY/wheelarea.scale
+            blockUpdates = false
+        }
+        Keys.onPressed: {
+            if (event.key == Qt.Key_PageUp) {
+                vscrollbar.value = vscrollbar.value - tree.height
+            } else if (event.key == Qt.Key_PageDown)
+                vscrollbar.value = vscrollbar.value + tree.height
+       }
+
+        onContentYChanged:  {
+            // positionViewAtIndex(currentIndex, ListView.Visible)
+            // highlight follows item
+            blockUpdates = true
+            vscrollbar.value = tree.contentY
+            blockUpdates = false
+        }
+
+        delegate: Item {
+            id: rowitem
+            width: row.width
+            height: row.height
+            anchors.margins: frameWidth
+            property int rowIndex: model.index
+            property bool itemAlternateBackground: alternateRowColor && rowIndex % 2 == 1
+            Loader {
+                id: rowstyle
+                // row delegate
+                sourceComponent: root.rowDelegate
+                // Row fills the tree width regardless of item size
+                // But scrollbar should not adjust to it
+                width: frameitem.width
+                height: row.height
+                x: contentX
+
+                property bool itemAlternateBackground: rowitem.itemAlternateBackground
+                property bool itemSelected: rowitem.ListView.isCurrentItem
+            }
+            Row {
+                id: row
+                anchors.left: parent.left
+
+                Repeater {
+                    id: repeater
+                    model: root.header.length
+                    Loader {
+                        id: itemDelegateLoader
+                        visible: header[index].visible
+                        sourceComponent: itemDelegate
+                        property variant model: tree.model
+                        property variant itemProperty: header[index].property
+
+                        width: header[index].width
+                        height: item ? item.height :  Math.max(16, styleitem.sizeFromContents(16, 16).height)
+
+                        function getValue() {
+                            if (index < header.length &&
+                                    root.model.get(rowIndex).hasOwnProperty(header[index].property))
+                                return root.model.get(rowIndex)[ header[index].property]
+                        }
+                        property variant itemValue: root.model.get(rowIndex)[ header[index].property]
+                        property bool itemSelected: rowitem.ListView.isCurrentItem
+                        property color itemForeground: itemSelected ? rowstyleitem.highlightedTextColor : rowstyleitem.textColor
+                        property int rowIndex: rowitem.rowIndex
+                        property int columnIndex: index
+                        property int itemElideMode: header[index].elideMode
+                    }
+                }
+                onWidthChanged: tree.contentWidth = width
+            }
+        }
+    }
+    Text{ id:text }
+
+    Item {
+        id: tableColumn
+        clip: true
+        anchors.top: frameitem.top
+        anchors.left: frameitem.left
+        anchors.right: frameitem.right
+        anchors.margins: frameWidth
+        visible: headerVisible
+        Behavior on height { NumberAnimation{duration:80}}
+        height: headerVisible ? styleitem.sizeFromContents(text.font.pixelSize, styleitem.fontHeight).height : frameWidth
+
+        Row {
+            id: headerrow
+
+            anchors.top: parent.top
+            height:parent.height
+            x: -tree.contentX
+
+            Repeater {
+                id: repeater
+                model: header.length
+                property int targetIndex: -1
+                property int dragIndex: -1
+                delegate: Item {
+                    z:-index
+                    width: header[index].width
+                    visible: header[index].visible
+                    height: headerrow.height
+
+                    Loader {
+                        sourceComponent: root.headerDelegate
+                        anchors.fill: parent
+                        property string itemValue: header[index].caption
+                        property string itemSort:  (sortIndicatorVisible && index == sortColumn) ? (sortIndicatorDirection == "up" ? "up" : "down") : "";
+                        property bool itemPressed: headerClickArea.pressed
+                        property bool itemContainsMouse: headerClickArea.containsMouse
+                    }
+                    Rectangle{
+                        id: targetmark
+                        width: parent.width
+                        height:parent.height
+                        opacity: (index == repeater.targetIndex && repeater.targetIndex != repeater.dragIndex) ? 0.5 : 0
+                        Behavior on opacity { NumberAnimation{duration:160}}
+                        color: palette.highlight
+                    }
+
+                    MouseArea{
+                        id: headerClickArea
+                        drag.axis: Qt.YAxis
+                        hoverEnabled: true
+                        anchors.fill: parent
+                        onClicked: {
+                            if (sortColumn == index)
+                                sortIndicatorDirection = sortIndicatorDirection === "up" ? "down" : "up"
+                            sortColumn = index
+                        }
+                        // Here we handle moving header sections
+                        onMousePositionChanged: {
+                            if (pressed) { // only do this while dragging
+                                for (var h = 0 ; h < header.length ; ++h) {
+                                    if (drag.target.x > headerrow.children[h].x - 10) {
+                                        repeater.targetIndex = header.length - h - 1
+                                        break
+                                    }
+                                }
+                            }
+                        }
+
+                        onPressed: {
+                            repeater.dragIndex = index
+                            draghandle.x = parent.x
+                        }
+
+                        onReleased: {
+                            if (repeater.targetIndex >= 0 && repeater.targetIndex != index ) {
+                                // Rearrange the header sections
+                                var items = new Array
+                                for (var i = 0 ; i< header.length ; ++i)
+                                    items.push(header[i])
+                                items.splice(index, 1);
+                                items.splice(repeater.targetIndex, 0, header[index]);
+                                header = items
+                                if (sortColumn == index)
+                                    sortColumn = repeater.targetIndex
+                            }
+                            repeater.targetIndex = -1
+                        }
+                        drag.maximumX: 1000
+                        drag.minimumX: -1000
+                        drag.target: draghandle
+                    }
+
+                    Loader {
+                        id: draghandle
+                        parent: tableColumn
+                        sourceComponent: root.headerDelegate
+                        width: header[index].width
+                        height: parent.height
+                        property string itemValue: header[index].caption
+                        property string itemSort:  (sortIndicatorVisible && index == sortColumn) ? (sortIndicatorDirection == "up" ? "up" : "down") : "";
+                        property bool itemPressed: headerClickArea.pressed
+                        property bool itemContainsMouse: headerClickArea.containsMouse
+                        visible: headerClickArea.pressed
+                        opacity: 0.5
+                    }
+
+
+                    MouseArea {
+                        id: headerResizeHandle
+                        property int offset: 0
+                        property int minimumSize: 20
+                        anchors.rightMargin: -width/2
+                        width: 16 ; height: parent.height
+                        anchors.right: parent.right
+                        onPositionChanged:  {
+                            var newHeaderWidth = header[index].width + (mouseX - offset)
+                            header[index].width = Math.max(minimumSize, newHeaderWidth)
+                        }
+                        property bool found:false
+
+                        onDoubleClicked: {
+                            var row
+                            var minWidth =  0
+                            var listdata = tree.children[0]
+                            for (row = 0 ; row < listdata.children.length ; ++row){
+                                var item = listdata.children[row+1]
+                                if (item && item.children[1] && item.children[1].children[index] &&
+                                        item.children[1].children[index].children[0].hasOwnProperty("implicitWidth"))
+                                    minWidth = Math.max(minWidth, item.children[1].children[index].children[0].implicitWidth)
+                            }
+                            if (minWidth)
+                                header[index].width = minWidth
+                        }
+                        onPressedChanged: if(pressed)offset=mouseX
+                        QStyleItem {
+                            anchors.fill: parent
+                            cursor: "splithcursor"
+                        }
+                    }
+                }
+            }
+        }
+        Loader {
+            id: loader
+            z:-1
+            sourceComponent: root.headerDelegate
+            anchors.top: parent.top
+            anchors.right: parent.right
+            anchors.bottom: headerrow.bottom
+            anchors.rightMargin: -2
+            width: root.width - headerrow.width
+            property string itemValue
+            property string itemSort
+            property bool itemPressed
+            property bool itemContainsMouse
+        }
+    }
+
+    WheelArea {
+        id: wheelarea
+        anchors.fill: parent
+        property int scale: 5
+        horizontalMinimumValue: hscrollbar.minimumValue/scale
+        horizontalMaximumValue: hscrollbar.maximumValue/scale
+        verticalMinimumValue: vscrollbar.minimumValue/scale
+        verticalMaximumValue: vscrollbar.maximumValue/scale
+
+        verticalValue: contentY/scale
+        horizontalValue: contentX/scale
+
+        onVerticalValueChanged: {
+            if(!tree.blockUpdates) {
+                contentY = verticalValue * scale
+                vscrollbar.value = contentY
+            }
+        }
+
+        onHorizontalValueChanged: {
+            if(!tree.blockUpdates) {
+                contentX = horizontalValue * scale
+                hscrollbar.value = contentX
+            }
+        }
+    }
+
+    ScrollBar {
+        id: hscrollbar
+        orientation: Qt.Horizontal
+        property int availableWidth: root.width - vscrollbar.width
+        visible: contentWidth > availableWidth
+        maximumValue: contentWidth > availableWidth ? tree.contentWidth - availableWidth : 0
+        minimumValue: 0
+        anchors.bottom: parent.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.leftMargin: frameWidth
+        anchors.bottomMargin: styleitem.frameoffset
+        anchors.rightMargin: vscrollbar.visible ? scrollbarExtent : (frame ? 1 : 0)
+        onValueChanged: {
+            if (!tree.blockUpdates)
+                contentX = value
+        }
+        property int scrollbarExtent : styleitem.pixelMetric("scrollbarExtent");
+    }
+
+    ScrollBar {
+        id: vscrollbar
+        orientation: Qt.Vertical
+        // We cannot bind directly to tree.height due to binding loops so we have to redo the calculation here
+        property int availableHeight : root.height - (hscrollbar.visible ? hscrollbar.height : 0) - tableColumn.height
+        visible: contentHeight > availableHeight
+        maximumValue: contentHeight > availableHeight ? tree.contentHeight - availableHeight : 0
+        minimumValue: 0
+        anchors.rightMargin: styleitem.frameoffset
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        anchors.topMargin: styleitem.style == "mac" ? tableColumn.height : 0
+        onValueChanged: {
+            if(!tree.blockUpdates)
+                contentY = value
+        }
+        anchors.bottomMargin: hscrollbar.visible ? hscrollbar.height :  styleitem.frameoffset
+
+        Keys.onUpPressed: if (tree.currentIndex > 0) tree.currentIndex = tree.currentIndex - 1
+        Keys.onDownPressed: if (tree.currentIndex< tree.count - 1) tree.currentIndex = tree.currentIndex + 1
+    }
+
+    QStyleItem {
+        z: 2
+        anchors.fill: parent
+        anchors.margins: -4
+        visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget")
+        elementType: "focusframe"
+    }
+
+    QStyleItem {
+        id: styleitem
+        elementType: "header"
+        visible:false
+        property int frameoffset: style === "mac" ? -1 : 0
+    }
+    QStyleItem {
+        id: rowstyleitem
+        elementType: "item"
+        visible:false
+        property color textColor: styleHint("textColor")
+        property color highlightedTextColor: styleHint("highlightedTextColor")
+    }
+    SystemPalette{id:palette}
+}
diff --git a/share/qtcreator/welcomescreen/components/TextArea.qml b/share/qtcreator/welcomescreen/components/TextArea.qml
new file mode 100644 (file)
index 0000000..440081f
--- /dev/null
@@ -0,0 +1,51 @@
+import QtQuick 1.0
+import "custom" 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
+    property alias readOnly: edit.readOnly
+
+    highlightOnFocus: true
+    property int documentMargins: 4
+    frame: true
+
+    Item {
+        anchors.left: parent.left
+        anchors.top: parent.top
+        height: edit.height - 8
+        anchors.margins: documentMargins
+
+        TextEdit {
+            id: edit
+            text: loremIpsum + loremIpsum;
+            wrapMode: TextEdit.WordWrap;
+            width: area.contentWidth
+            selectByMouse: true
+            readOnly: false
+            focus: true
+
+            // keep textcursor within scrollarea
+            onCursorPositionChanged: {
+                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
+            }
+        }
+    }
+
+    Keys.onPressed: {
+        if (event.key == Qt.Key_PageUp) {
+            verticalValue = verticalValue - area.height
+        } else if (event.key == Qt.Key_PageDown)
+            verticalValue = verticalValue + area.height
+   }
+}
diff --git a/share/qtcreator/welcomescreen/components/TextField.qml b/share/qtcreator/welcomescreen/components/TextField.qml
new file mode 100644 (file)
index 0000000..ccadadf
--- /dev/null
@@ -0,0 +1,42 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.TextField {
+    id: textfield
+    minimumWidth: 200
+
+    placeholderText: ""
+    topMargin: 2
+    bottomMargin: 2
+    leftMargin: 6
+    rightMargin: 6
+
+    height:  backgroundItem.sizeFromContents(200, 25).height
+    width: 200
+    clip: false
+
+    background: QStyleItem {
+        anchors.fill: parent
+        elementType: "edit"
+        sunken: true
+        focus: textfield.activeFocus
+        hover: containsMouse
+    }
+
+    Item{
+        id: focusFrame
+        anchors.fill: textfield
+        parent: textfield
+        visible: framestyle.styleHint("focuswidget")
+        QStyleItem {
+            id: framestyle
+            anchors.margins: -2
+            anchors.rightMargin:-4
+            anchors.bottomMargin:-4
+            anchors.fill: parent
+            visible: textfield.activeFocus
+            elementType: "focusframe"
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/ToolBar.qml b/share/qtcreator/welcomescreen/components/ToolBar.qml
new file mode 100644 (file)
index 0000000..9836772
--- /dev/null
@@ -0,0 +1,11 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+QStyleItem{
+    id: toolbar
+    width: 200
+    height: sizeFromContents(32, 32).height
+    elementType: "toolbar"
+}
+
diff --git a/share/qtcreator/welcomescreen/components/ToolButton.qml b/share/qtcreator/welcomescreen/components/ToolButton.qml
new file mode 100644 (file)
index 0000000..7de72fd
--- /dev/null
@@ -0,0 +1,34 @@
+import QtQuick 1.0
+import "custom" as Components
+import "plugin"
+
+Components.Button {
+    id:button
+
+    height: 40; //styleitem.sizeFromContents(32, 32).height
+    width: 40; //styleitem.sizeFromContents(32, 32).width
+
+    QStyleItem {elementType: "toolbutton"; id:styleitem  }
+
+    background: QStyleItem {
+        anchors.fill: parent
+        id: styleitem
+        elementType: "toolbutton"
+        on: pressed | checked
+        sunken: pressed
+        raised: containsMouse
+        hover: containsMouse
+
+        Text {
+            text: button.text
+            anchors.centerIn: parent
+            visible: button.iconSource == ""
+        }
+
+        Image {
+            source: button.iconSource
+            anchors.centerIn: parent
+            opacity: enabled ? 1 : 0.5
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/components.pro b/share/qtcreator/welcomescreen/components/components.pro
new file mode 100644 (file)
index 0000000..83e0a3d
--- /dev/null
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = styleitem
diff --git a/share/qtcreator/welcomescreen/components/custom/BasicButton.qml b/share/qtcreator/welcomescreen/components/custom/BasicButton.qml
new file mode 100644 (file)
index 0000000..ee591e2
--- /dev/null
@@ -0,0 +1,51 @@
+import QtQuick 1.0
+import "./behaviors"    // ButtonBehavior
+
+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: null
+    property Item backgroundItem: backgroundLoader.item
+
+    property color textColor: syspal.text;
+    property bool activeFocusOnPress: true
+    property string tooltip
+
+    signal toolTipTriggered
+
+    // implementation
+
+    property string __position: "only"
+    width: backgroundLoader.item.width
+    height: 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()
+        onPressedChanged: if (activeFocusOnPress) button.focus = true
+        onMouseMoved: {tiptimer.restart()}
+        Timer{
+            id: tiptimer
+            interval:1000
+            running:containsMouse && tooltip.length
+            onTriggered: button.toolTipTriggered()
+        }
+    }
+
+    SystemPalette { id: syspal }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/Button.qml b/share/qtcreator/welcomescreen/components/custom/Button.qml
new file mode 100644 (file)
index 0000000..45abc83
--- /dev/null
@@ -0,0 +1,21 @@
+import QtQuick 1.0
+
+BasicButton {
+    id: button
+
+    property string text
+    property url iconSource
+    property Component label: null
+
+    // implementation
+
+    background: defaultStyle.background
+    property Item labelItem: labelLoader.item
+
+    Loader {
+        id: labelLoader
+        anchors.fill: parent
+        property alias styledItem: button
+        sourceComponent: label
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/ButtonColumn.qml b/share/qtcreator/welcomescreen/components/custom/ButtonColumn.qml
new file mode 100644 (file)
index 0000000..8d63a85
--- /dev/null
@@ -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/share/qtcreator/welcomescreen/components/custom/ButtonGroup.js b/share/qtcreator/welcomescreen/components/custom/ButtonGroup.js
new file mode 100644 (file)
index 0000000..19d05fe
--- /dev/null
@@ -0,0 +1,137 @@
+var self;
+var checkHandlers = [];
+var visibleButtons = [];
+var nonVisibleButtons = [];
+var direction;
+
+function create(that, options) {
+    self = that;
+    direction = options.direction || Qt.Horizontal;
+    self.childrenChanged.connect(rebuild);
+//    self.widthChanged.connect(resizeChildren);
+    build();
+}
+
+function isButton(item) {
+    if (item && item.hasOwnProperty("__position"))
+        return true;
+    return false;
+}
+
+function hasChecked(item) {
+    return (item && item.hasOwnProperty("checked"));
+}
+
+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 (self.exclusive && item.hasOwnProperty("checkable"))
+            item.checkable = true;
+
+        if (self.exclusive) {
+            item.checked = false;
+            checkHandlers.push(checkExclusive(item));
+            item.checkedChanged.connect(checkHandlers[checkHandlers.length - 1]);
+        }
+    }
+
+    var nrButtons = visibleButtons.length;
+    if (nrButtons == 0)
+        return;
+
+    if (self.checkedButton)
+        self.checkedButton.checked = true;
+    else if (self.exclusive) {
+        self.checkedButton = visibleButtons[0];
+        self.checkedButton.checked = true;
+    }
+
+    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     //mm How to make this not cause binding loops? see QTBUG-17162
+            button.anchors.right = self.right
+        }
+    }
+}
+
+function cleanup() {
+    visibleButtons.forEach(function(item, i) {
+        if (checkHandlers[i])
+            item.checkedChanged.disconnect(checkHandlers[i]);
+        item.visibleChanged.disconnect(rebuild);
+    });
+    checkHandlers = [];
+
+    nonVisibleButtons.forEach(function(item, i) {
+        item.visibleChanged.disconnect(rebuild);
+    });
+}
+
+function rebuild() {
+    if (self == undefined)
+        return;
+
+    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++) {
+            if (ref.checked == (button === ref))
+                continue;
+
+            // Disconnect the signal to avoid recursive calls
+            ref.checkedChanged.disconnect(checkHandlers[i]);
+            ref.checked = !ref.checked;
+            ref.checkedChanged.connect(checkHandlers[i]);
+        }
+        self.checkedButton = button;
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/ButtonRow.qml b/share/qtcreator/welcomescreen/components/custom/ButtonRow.qml
new file mode 100644 (file)
index 0000000..7c2d3ea
--- /dev/null
@@ -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/share/qtcreator/welcomescreen/components/custom/CheckBox.qml b/share/qtcreator/welcomescreen/components/custom/CheckBox.qml
new file mode 100644 (file)
index 0000000..a49d71d
--- /dev/null
@@ -0,0 +1,32 @@
+import QtQuick 1.0
+import "./behaviors"
+
+Item {
+    id: checkBox
+
+    signal clicked
+    property alias pressed: behavior.pressed
+    property alias checked: behavior.checked
+    property alias containsMouse: behavior.containsMouse
+    property bool activeFocusOnPress: true
+    property Component background: null
+    property Item backgroundItem: backgroundLoader.item
+
+    // implementation
+
+    Loader {
+        id: backgroundLoader
+        anchors.fill: parent
+        property alias styledItem: checkBox
+        sourceComponent: background
+    }
+
+    ButtonBehavior {
+        id: behavior
+        anchors.fill: parent
+        checkable: true
+        onClicked: {if (activeFocusOnPress)checkBox.focus = true; checkBox.clicked()}
+    }
+
+    SystemPalette { id: syspal }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/ChoiceList.qml b/share/qtcreator/welcomescreen/components/custom/ChoiceList.qml
new file mode 100644 (file)
index 0000000..a316f04
--- /dev/null
@@ -0,0 +1,49 @@
+import QtQuick 1.0
+import "./private" as Private
+
+Item {
+    id: choiceList
+
+    property alias model: popup.model
+    property alias currentIndex: popup.currentIndex
+    property alias currentText: popup.currentText
+    property alias popupOpen: popup.popupOpen
+    property alias containsMouse: popup.containsMouse
+    property alias pressed: popup.buttonPressed
+
+    property Component background: null
+    property Item backgroundItem: backgroundLoader.item
+    property Component listItem: null
+    property Component popupFrame: null
+
+    property int leftMargin: 0
+    property int topMargin: 0
+    property int rightMargin: 0
+    property int bottomMargin: 0
+
+    property string popupBehavior
+    width: 0
+    height: 0
+
+    property bool activeFocusOnPress: true
+
+    Loader {
+        id: backgroundLoader
+        property alias styledItem: choiceList
+        sourceComponent: background
+        anchors.fill: parent
+        property string currentItemText: model.get(currentIndex).text
+    }
+
+    Private.ChoiceListPopup {
+        // NB: This ChoiceListPopup is also the mouse area
+        // for the component (to enable drag'n'release)
+        id: popup
+        listItem: choiceList.listItem
+        popupFrame: choiceList.popupFrame
+    }
+
+    Keys.onSpacePressed: { choiceList.popupOpen = !choiceList.popupOpen }
+    Keys.onUpPressed: { if (currentIndex < model.count - 1) currentIndex++ }
+    Keys.onDownPressed: {if (currentIndex > 0) currentIndex-- }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/GroupBox.qml b/share/qtcreator/welcomescreen/components/custom/GroupBox.qml
new file mode 100644 (file)
index 0000000..ab1117e
--- /dev/null
@@ -0,0 +1,54 @@
+import QtQuick 1.0
+
+FocusScope {
+    id: groupbox
+
+    width: Math.max(200, contentWidth + loader.leftMargin + loader.rightMargin)
+    height: contentHeight + loader.topMargin + loader.bottomMargin
+
+    default property alias children: content.children
+
+    property string title
+    property bool checkable: false
+    property int contentWidth: content.childrenRect.width
+    property int contentHeight: content.childrenRect.height
+    property double contentOpacity: 1
+
+    property Component background: null
+    property Item backgroundItem: loader.item
+
+    property CheckBox checkbox: check
+    property alias checked: check.checked
+
+    Loader {
+        id: loader
+        anchors.fill: parent
+        property int topMargin: 22
+        property int bottomMargin: 4
+        property int leftMargin: 4
+        property int rightMargin: 4
+
+        property alias styledItem: groupbox
+        sourceComponent: background
+
+        Item {
+            id:content
+            z: 1
+            opacity: contentOpacity
+            anchors.topMargin: loader.topMargin
+            anchors.leftMargin: 8
+            anchors.top:parent.top
+            anchors.left:parent.left
+            enabled: (!checkable || checkbox.checked)
+        }
+
+        CheckBox {
+            id: check
+            checked: true
+            anchors.top: parent.top
+            anchors.left: parent.left
+            anchors.right: parent.right
+            height: loader.topMargin
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/ProgressBar.qml b/share/qtcreator/welcomescreen/components/custom/ProgressBar.qml
new file mode 100644 (file)
index 0000000..3ad8bca
--- /dev/null
@@ -0,0 +1,53 @@
+import QtQuick 1.0
+
+Item {
+    id: progressBar
+
+    property real value: 0
+    property real minimumValue: 0
+    property real maximumValue: 1
+    property bool indeterminate: false
+    property bool containsMouse: mouseArea.containsMouse
+
+    property int leftMargin: 0
+    property int topMargin: 0
+    property int rightMargin: 0
+    property int bottomMargin: 0
+
+    property int minimumWidth: 0
+    property int minimumHeight: 0
+
+    width: minimumWidth
+    height: minimumHeight
+
+    property Component background: null
+    property Item backgroundItem: groove.item
+
+    property color backgroundColor: syspal.base
+    property color progressColor: syspal.highlight
+
+    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
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/Slider.qml b/share/qtcreator/welcomescreen/components/custom/Slider.qml
new file mode 100644 (file)
index 0000000..f551baa
--- /dev/null
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** 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 "../"
+
+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
+    property alias hoverEnabled: mouseArea.hoverEnabled
+
+    // 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
+    property bool containsMouse: mouseArea.containsMouse
+
+    // CONVENIENCE TO BE USED BY STYLES
+
+    property int leftMargin: 0
+    property int rightMargin: 0
+
+    // 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
+    property bool activeFocusOnPress: 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);
+    }
+
+    // Hooks for customizing the pieces of the slider
+    property Component groove: null
+    property Component handle: null
+    property Component valueIndicator: null
+
+    // PRIVATE/CONVENIENCE
+    property bool _isVertical: orientation == Qt.Vertical
+
+    // 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.0
+            maximumValue: 1.0
+            value: 0
+            stepSize: 0.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
+            hoverEnabled: true
+            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: {
+
+                if (activeFocusOnPress)
+                    slider.focus = true;
+
+                // 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.
+
+                // Note this really messes up things for scrollbar
+                // 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/share/qtcreator/welcomescreen/components/custom/SpinBox.qml b/share/qtcreator/welcomescreen/components/custom/SpinBox.qml
new file mode 100644 (file)
index 0000000..1110ff8
--- /dev/null
@@ -0,0 +1,164 @@
+import QtQuick 1.0
+
+FocusScope {
+    id: spinbox
+    SystemPalette{id:syspal}
+
+    property int minimumWidth: 0
+    property int minimumHeight: 0
+
+    property int leftMargin: 0
+    property int topMargin: 0
+    property int rightMargin: 0
+    property int bottomMargin: 0
+
+    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 string postfix
+
+    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 color textColor: syspal.text
+    property alias font: input.font
+
+    property Component background: null
+    property Item backgroundItem: backgroundComponent.item
+    property Component up: null
+    property Component down: null
+
+    QtObject {
+        id: componentPrivate
+        property bool valueUpdate: false
+    }
+
+    function increment() {
+        setValue(input.text)
+        value += singleStep
+        if (value > maximumValue)
+            value = maximumValue
+        input.text = value
+    }
+
+    function decrement() {
+        setValue(input.text)
+        value -= singleStep
+        if (value < minimumValue)
+            value = minimumValue
+        input.text = value
+    }
+
+    function setValue(v) {
+        var newval = parseFloat(v)
+        if (newval > maximumValue)
+            newval = maximumValue
+        else if (v < minimumValue)
+            newval = minimumValue
+        value = newval
+        input.text = value
+    }
+
+    Component.onCompleted: setValue(value)
+
+    onValueChanged: {
+        componentPrivate.valueUpdate = true
+        input.text = value
+        componentPrivate.valueUpdate = false
+    }
+
+    // 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
+
+        // validator: DoubleValidator { bottom: minimumValue; top: maximumValue; }
+        onAccepted: {setValue(input.text)}
+        onActiveFocusChanged: setValue(input.text)
+        color: textColor
+        opacity: parent.enabled ? 1 : 0.5
+        Text {
+            text: postfix
+            anchors.rightMargin: 4
+            anchors.right: parent.right
+            anchors.verticalCenter: parent.verticalCenter
+        }
+    }
+
+    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
+        }
+    }
+    Keys.onUpPressed: increment()
+    Keys.onDownPressed: decrement()
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/SplitterRow.qml b/share/qtcreator/welcomescreen/components/custom/SplitterRow.qml
new file mode 100644 (file)
index 0000000..adf73f3
--- /dev/null
@@ -0,0 +1,328 @@
+import QtQuick 1.0
+import "private"
+
+/*
+*
+* SplitterRow
+*
+* SplitterRow is a component that provides a way to layout items horisontally with
+* a draggable splitter added in-between each item.
+*
+* Add items to the SplitterRow by inserting them as child items. The splitter handle
+* is outsourced as a delegate (handleBackground). For this delegate to work properly,
+* it will need to contain a mouse area that communicates with the SplitterRow by binding
+* 'onMouseXChanged: handleDragged(handleIndex)', and 'drag.target: dragTarget'.
+*
+* The SplitterRow contains the followin API:
+*
+* Component handleBackground - delegate that will be instanciated between each
+*   child item. Inside the delegate, the following properties are available:
+*   int handleIndex - specifies the index of the splitter handle. The handle
+*       between the first and the second item will get index 0, the next handle index 1 etc.
+*   Item handleDragTarget - convenience property that tells which drag target any
+*       inner mouse areas that controls the handle should bind to.
+*   function handleDragged(handleIndex) - function that should be called whenever
+*       the handle is dragged to a new position
+*
+* The following properties can optionally be added for each direct child item of SplitterRow:
+*
+* real minimumWidth - if present, ensures that the item cannot be resized below the
+*   given value. A value of -1 will disable it.
+* real maximumWidth - if present, ensures that the item cannot be resized above the
+*   given value. A value of -1 will disable it.
+* real percentageWidth - if present, should be a value between 0-100. This value specifies
+*   a percentage of the width of the SplitterRow width. If the width of the SplitterRow
+*   change, the width of the item will change as well. 'percentageWidth' have precedence
+*   over 'width', which means that SplitterRow will ignore any assignments done to 'width'.
+*   A value of -1 disables it.
+* bool expanding - if present, the item will consume all extra space in the SplitterRow, down to
+*   minimumWidth. This means that that 'width', 'percentageWidth' and 'maximumWidth' will be ignored.
+*   There will always be one (and only one) item in the SplitterRow that has this behaviour, and by
+*   default, it will be the last child item of the SplitterRow. Also note that which item that gets
+*   resized upon dragging a handle depends on whether the expanding item is located towards the left
+*   or the right of the handle.
+*
+* Example:
+*
+* To create a SplitterRow with three items, and let
+* the center item be the one that should be expanding, one
+* could do the following:
+*
+*    SplitterRow {
+*        anchors.fill: parent
+*
+*        handleBackground: Rectangle {
+*            width: 1
+*            color: "black"
+*
+*            MouseArea {
+*                anchors.fill: parent
+*                anchors.leftMargin: -2
+*                anchors.rightMargin: -2
+*                drag.axis: Qt.YAxis
+*                drag.target: handleDragTarget
+*                onMouseXChanged: handleDragged(handleIndex)
+*            }
+*        }
+*
+*        Rectangle {
+*            color: "gray"
+*            width: 200
+*        }
+*        Rectangle {
+*            property real minimumWidth: 50
+*            property real maximumWidth: 400
+*            property bool expanding: true
+*            color: "darkgray"
+*        }
+*        Rectangle {
+*            color: "gray"
+*            width: 200
+*        }
+*    }
+*/
+
+Item {
+    id: root
+    default property alias items: splitterItems.children
+    property alias handles: splitterHandles.children
+    property Component handleBackground: Rectangle { width:3; color: "black" }
+    clip: true
+
+    Component.onCompleted: d.init();
+    onWidthChanged: d.updateLayout();
+
+    QtObject {
+        id: d
+        property int expandingIndex: items.length-1
+        property bool updateOptimizationBlock: true
+        property bool bindingRecursionGuard: false
+
+        function init()
+        {
+            for (var i=0; i<items.length-1; ++i) {
+                // Anchor each item to fill out all space vertically:
+                var item = items[i];
+                item.anchors.top = splitterItems.top
+                item.anchors.bottom = splitterItems.bottom
+                // Listen for changes to width and expanding:
+                propertyChangeListener.createObject(item);
+                // Create a handle for the item:
+                var handle = handleBackgroundLoader.createObject(splitterHandles, {"handleIndex":i});
+                handle.anchors.top = splitterHandles.top
+                handle.anchors.bottom = splitterHandles.bottom
+            }
+            item = items[i]
+            if (item) {
+                // Do the same for the last item as well, since
+                // the for-loop skipped the last item:
+                items[i].anchors.top = splitterItems.top
+                items[i].anchors.bottom = splitterItems.bottom
+                propertyChangeListener.createObject(items[i]);
+            }
+            d.updateOptimizationBlock = false
+            d.updateLayout()
+        }
+
+        function accumulatedWidth(firstIndex, lastIndex, includeExpandingMinimum)
+        {
+            // Go through items and handles, and
+            // calculate their acummulated width.
+            var w = 0
+            for (var i=firstIndex; i<lastIndex; ++i) {
+                var item = items[i]
+                if (i !== d.expandingIndex)
+                    w += item.width;
+                else if (includeExpandingMinimum && item.minimumWidth != undefined && item.minimumWidth != -1)
+                    w += item.minimumWidth
+                if (handles[i] && (i !== d.expandingIndex || includeExpandingMinimum === false))
+                    w += handles[i].width
+            }
+            return w
+        }
+
+        function updateLayout()
+        {
+            if (items.length === 0)
+                return;
+            if (d.updateOptimizationBlock === true)
+                return
+            d.updateOptimizationBlock = true
+
+            // This function will reposition both handles and
+            // items according to the _width of the each item_
+            var item, prevItem
+            var handle, prevHandle
+            var newValue
+
+            // Ensure all items within min/max:
+            for (var i=0; i<items.length; ++i) {
+                if (i !== d.expandingIndex) {
+                    item = items[i];
+                    // If the item is using percentage width, convert
+                    // that number to real width now:
+                    if (item.percentageWidth != undefined && item.percentageWidth !== -1) {
+                        newValue = item.percentageWidth * (root.width / 100)
+                        if (newValue !== item.width)
+                            item.width = newValue
+                    }
+                    // Ensure item width is not more than maximumWidth:
+                    if (item.maximumWidth != undefined && item.maximumWidth != -1) {
+                        newValue = Math.min(item.width, item.maximumWidth)
+                        if (newValue !== item.width)
+                            item.width = newValue
+                    }
+                    // Ensure item width is not more less minimumWidth:
+                    if (item.minimumWidth != undefined && item.minimumWidth != -1) {
+                        newValue = Math.max(item.width, item.minimumWidth)
+                        if (newValue !== item.width)
+                            item.width = newValue
+                    }
+                }
+            }
+
+            // Special case: set width of expanding item to available space:
+            newValue = root.width - d.accumulatedWidth(0, items.length, false);
+            var expandingItem = items[d.expandingIndex]
+            if (expandingItem.minimumWidth != undefined && expandingItem.minimumWidth != -1)
+                newValue = Math.max(newValue, expandingItem.minimumWidth)
+            if (expandingItem.width !== newValue)
+                expandingItem.width = newValue
+
+            // Then, position items and handles according to their width:
+            for (i=0; i<items.length; ++i) {
+                item = items[i];
+                handle = handles[i]
+
+                // Position item to the right of the previus handle:
+                if (prevHandle) {
+                    newValue = prevHandle.x + prevHandle.width
+                    if (newValue !== item.x)
+                        item.x = newValue
+                }
+
+                // Position handle to the right of item:
+                if (handle) {
+                    newValue = item.x + Math.max(0, item.width)
+                    if (newValue !== handle.x)
+                        handle.x = newValue
+                }
+
+                prevItem = item
+                prevHandle = handle
+            }
+
+            d.updateOptimizationBlock = false
+        }
+    }
+
+    Component {
+        id: handleBackgroundLoader
+        Loader {
+            id: loader
+            property int handleIndex: 0
+            property Item handleDragTarget: loader
+            sourceComponent: handleBackground
+
+            function handleDragged(handleIndex)
+            {
+                // Moving the handle means resizing an item. Which one,
+                // left or right, depends on where the expanding item is.
+                // 'updateLayout' will override in case new width violates max/min.
+                // And 'updateLayout will be triggered when an item changes width.
+
+                var leftHandle, leftItem, handle, rightItem, rightHandle
+                var leftEdge, rightEdge, newWidth
+
+                handle = handles[handleIndex]
+
+                if (d.expandingIndex > handleIndex) {
+                    // Resize item to the left.
+                    // Ensure that the handle is not crossing other handles:
+                    leftHandle = handles[handleIndex-1]
+                    leftItem = items[handleIndex]
+                    leftEdge = leftHandle ? (leftHandle.x + leftHandle.width) : 0
+                    handle.x = Math.max(leftEdge, handle.x)
+                    newWidth = handle.x - leftEdge
+                    if (root.width != 0 && leftItem.percentageWidth != undefined && leftItem.percentageWidth !== -1)
+                        leftItem.percentageWidth = newWidth * (100 / root.width)
+                    // The next line will trigger 'updateLayout' inside 'propertyChangeListener':
+                    leftItem.width = newWidth
+                } else {
+                    // Resize item to the right:
+                    // Since the first item in the splitter always will have x=0, we need
+                    // to ensure that the user cannot drag the handle more left than what
+                    // we got space for:
+                    var min = d.accumulatedWidth(0, handleIndex+1, true)
+                    // Ensure that the handle is not crossing other handles:
+                    rightItem = items[handleIndex+1]
+                    rightHandle = handles[handleIndex+1]
+                    rightEdge = (rightHandle ? rightHandle.x : root.width)
+                    handle.x = Math.max(min, Math.max(Math.min((rightEdge - handle.width), handle.x)))
+                    newWidth = rightEdge - (handle.x + handle.width)
+                    if (root.width != 0 && rightItem.percentageWidth != undefined && rightItem.percentageWidth !== -1)
+                        rightItem.percentageWidth = newWidth * (100 / root.width)
+                    // The next line will trigger 'updateLayout' inside 'propertyChangeListener':
+                    rightItem.width = newWidth
+                }
+            }
+        }
+    }
+
+    Item {
+        id: splitterItems
+        anchors.fill: parent
+    }
+    Item {
+        id: splitterHandles
+        anchors.fill: parent
+    }
+
+    Component {
+        // This dummy item becomes a child of all
+        // items it the splitter, just to provide a way
+        // to listed for changes to their width, expanding etc.
+        id: propertyChangeListener
+        Item {
+            id: target
+            width: parent.width
+            property bool expanding: (parent.expanding != undefined) ? parent.expanding : false
+            property real percentageWidth: (parent.percentageWidth != undefined) ? parent.percentageWidth : -1
+            property real minimumWidth: (parent.minimumWidth != undefined) ? parent.minimumWidth : -1
+            property real maximumWidth: (parent.maximumWidth != undefined) ? parent.maximumWidth : -1
+
+            onPercentageWidthChanged: d.updateLayout();
+            onMinimumWidthChanged: d.updateLayout();
+            onMaximumWidthChanged: d.updateLayout();
+
+            onExpandingChanged: {
+                // Find out which item that has the expanding flag:
+                for (var i=0; i<items.length; ++i) {
+                    var item = items[i]
+                    if (item.expanding && item.expanding === true) {
+                        d.expandingIndex = i
+                        d.updateLayout();
+                        return
+                    }
+                }
+                d.expandingIndex = i-1
+                updateLayout();
+            }
+
+            onWidthChanged: {
+                // We need to update the layout:
+                if (d.bindingRecursionGuard === true)
+                    return
+                d.bindingRecursionGuard = true
+
+                // Break binding:
+                width = 0
+                d.updateLayout()
+                // Restablish binding:
+                width = function() { return parent.width; }
+                
+                d.bindingRecursionGuard = false
+            }
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/TextField.qml b/share/qtcreator/welcomescreen/components/custom/TextField.qml
new file mode 100644 (file)
index 0000000..b38b3ec
--- /dev/null
@@ -0,0 +1,125 @@
+import QtQuick 1.0
+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: mouseArea.containsMouse
+
+    property Component background: null
+    property Component hints: null
+    property Item backgroundItem: backgroundLoader.item
+
+    property int minimumWidth: 0
+    property int minimumHeight: 0
+
+    property int leftMargin: 0
+    property int topMargin: 0
+    property int rightMargin: 0
+    property int bottomMargin: 0
+
+    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)
+
+    // Implementation
+    clip: true
+
+    SystemPalette { id: syspal }
+    Loader { id: hintsLoader; sourceComponent: hints }
+    Loader { id: backgroundLoader; sourceComponent: background; anchors.fill:parent}
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+    }
+
+    TextInput { // see QTBUG-14936
+        id: textInput
+        selectByMouse:true
+        font.pixelSize: hintsLoader.item != null ? hintsLoader.item.fontPixelSize: 14
+        font.bold: hintsLoader.item != null ? hintsLoader.item.fontBold : false
+
+        anchors.leftMargin: leftMargin
+        anchors.topMargin: topMargin
+        anchors.rightMargin: rightMargin
+        anchors.bottomMargin: bottomMargin
+
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.verticalCenter: parent.verticalCenter
+
+        color: enabled ? textColor : Qt.tint(textColor, "#80ffffff")
+        echoMode: passwordMode ? _hints.passwordEchoMode : TextInput.Normal
+    }
+
+    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 } }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/components/custom/behaviors/ButtonBehavior.qml b/share/qtcreator/welcomescreen/components/custom/behaviors/ButtonBehavior.qml
new file mode 100644 (file)
index 0000000..57ea626
--- /dev/null
@@ -0,0 +1,33 @@
+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
+    signal mouseMoved
+
+    onCheckableChanged: { if(!checkable) checked = false }
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+        onPositionChanged: behavior.mouseMoved()
+        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/share/qtcreator/welcomescreen/components/custom/behaviors/ModalPopupBehavior.qml b/share/qtcreator/welcomescreen/components/custom/behaviors/ModalPopupBehavior.qml
new file mode 100644 (file)
index 0000000..108bf02
--- /dev/null
@@ -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/share/qtcreator/welcomescreen/components/custom/components.pro b/share/qtcreator/welcomescreen/components/custom/components.pro
new file mode 100644 (file)
index 0000000..be0663d
--- /dev/null
@@ -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/share/qtcreator/welcomescreen/components/custom/private/ChoiceListPopup.qml b/share/qtcreator/welcomescreen/components/custom/private/ChoiceListPopup.qml
new file mode 100644 (file)
index 0000000..5ed7f27
--- /dev/null
@@ -0,0 +1,323 @@
+import QtQuick 1.0
+
+MouseArea {
+    id: popup
+
+    // There is no global z-ordering that can stack this popup in front, so we
+    // need to reparent it to the root item to fake it upon showing the popup.
+    // In that case, the popup will also fill the whole window to allow the user to
+    // close the popup by clicking anywhere in the window. Letting the popup act as the mouse
+    // area for the button that 'owns' it is also nessesary to support drag'n'release behavior.
+
+    // The 'popupframe' delegate will be told to show or hide by assigning
+    // opacity to 1 or 0, respectively.
+
+    anchors.fill: parent
+    hoverEnabled: true    
+
+
+
+    // Set 'popupOpen' to show/hide the popup. The 'state' property is more
+    // internal, and contains additional states used to protect the popup from
+    // e.g. receiving mouse clicks while its about to hide etc.
+    property bool popupOpen: false
+
+    property bool desktopBehavior: true
+    property int previousCurrentIndex: -1
+    property alias model: listView.model
+    property alias currentIndex: listView.currentIndex
+    property string currentText: model && currentIndex >= 0 ? model.get(currentIndex).text : ""
+
+    // buttonPressed will be true when the mouse press starts
+    // while the popup is closed. At that point, this component can be
+    // seen as a button, and not yet a popup menu:
+    property bool buttonPressed: false
+
+    property Component listItem
+    property Component listHighlight
+    property Component popupFrame
+
+    property Item originalParent: parent
+
+    onPopupOpenChanged: {
+        if (popupFrameLoader.item === null)
+            return;
+        if (popupOpen) {
+            var oldMouseX = mouseX
+
+            // Reparent to root, so the popup stacks in front:
+            originalParent = parent;
+            var p = parent;
+            while (p.parent != undefined)
+                p = p.parent
+            parent = p;
+
+            previousCurrentIndex = currentIndex;
+            positionPopup();
+            popupFrameLoader.item.opacity = 1;
+            if (oldMouseX === mouseX){
+                // Work around bug: mouseX and mouseY does not immidiatly
+                // update after reparenting and resizing the mouse area:
+                var pos = originalParent.mapToItem(parent, mouseX, mouseY)
+                highlightItemAt(pos.x, pos.y);
+            } else {
+                highlightItemAt(mouseX, mouseY);
+            }
+            listView.forceActiveFocus();
+            state = "popupOpen"
+        } else {
+            popupFrameLoader.item.opacity = 0;
+            popup.hideHighlight();
+            state = "popupClosed"
+        }
+    }
+
+    Component.onCompleted: {
+        // In case 'popupOpen' was set to 'true' before
+        // 'popupFrameLoader' was finished, we open the popup now instead:
+        if (popup.popupOpen){
+            popup.popupOpen = false
+            popup.popupOpen = true
+        }
+    }
+
+    function highlightItemAt(posX, posY)
+    {
+        var mappedPos = mapToItem(listView.contentItem, posX, posY);
+        var indexAt = listView.indexAt(mappedPos.x, mappedPos.y);
+        if (indexAt == listView.highlightedIndex)
+            return;
+        if (indexAt >= 0) {
+            listView.highlightedIndex = indexAt;
+        } else {
+            if(posY > listView.y+listView.height && listView.highlightedIndex+1 < listView.count ) {
+                listView.highlightedIndex++;
+            } else if(posY < listView.y && listView.highlightedIndex > 0) {
+                listView.highlightedIndex--;
+            } else if(posX < popupFrameLoader.x || posX > popupFrameLoader.x+popupFrameLoader.width) {
+                popup.hideHighlight();
+            }
+        }
+    }
+
+    function hideHighlight() {
+        listView.highlightedIndex = -1;
+        listView.highlightedItem = null; // will trigger positionHighlight() what will hide the highlight
+    }
+
+    function positionPopup() {
+        // Set initial values to top left corner of original parent:
+        var globalPos = mapFromItem(originalParent, 0, 0);
+        var newX = globalPos.x;
+        var newY = globalPos.y
+        var newW = originalParent.width;
+        var newH = listView.contentHeight
+
+        switch (popupFrameLoader.item.popupLocation) {
+        case "center":
+            // Show centered over original parent with respect to selected item:
+            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
+            newY -= currentItemY;
+            break;
+        case "below":
+        case "":
+            // Show below original parent:
+            newX -= popupFrameLoader.anchors.leftMargin;
+            newY += originalParent.height - popupFrameLoader.anchors.topMargin;
+            break;
+        }
+
+        // Ensure the popup is inside the window:
+        if (newX < popupFrameLoader.anchors.leftMargin)
+            newX = popupFrameLoader.anchors.leftMargin;
+        else if (newX + newW > popup.width - popupFrameLoader.anchors.rightMargin)
+            newX = popup.width - popupFrameLoader.anchors.rightMargin - newW;
+
+        if (newY < popupFrameLoader.anchors.topMargin)
+            newY = popupFrameLoader.anchors.topMargin;
+        else if (newY + newH > popup.height - popupFrameLoader.anchors.bottomMargin)
+            newY = popup.height - popupFrameLoader.anchors.bottomMargin - newH;
+
+        // Todo: handle case when the list itself is larger than the window...
+
+        listView.x = newX
+        listView.y = newY
+        listView.width = newW
+        listView.height = newH
+    }
+
+    Loader {
+        id: popupFrameLoader
+        property alias styledItem: popup.originalParent
+        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
+        onItemChanged: item.opacity = 0
+    }
+
+    ListView {
+        id: listView
+        focus: true
+        opacity: popupFrameLoader.item.opacity
+        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
+            }
+        }
+
+        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 'index'
+
+            Loader {
+                id: delegateLoader
+                property variant model: listView.model
+                property alias index: itemDelegate.theIndex
+                property Item styledItem: choiceList
+                property bool highlighted: theIndex == listView.highlightedIndex
+                property string itemText: popup.model.get(theIndex).text
+                sourceComponent: listItem
+            }
+
+            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) {
+                    listView.currentIndex = highlightedIndex;
+                } else {
+                    listView.currentIndex = popup.previousCurrentIndex;
+                }
+
+                popup.popupOpen = false;
+            } else if (event.key == Qt.Key_Escape) {
+                listView.currentIndex = popup.previousCurrentIndex;
+                popup.popupOpen = false;
+            }
+            event.accepted = true;  // consume all keys while popout has focus
+        }
+
+        highlight: popup.listHighlight
+    }
+
+    Timer {
+        // This is the time-out value for when we consider the
+        // user doing a press'n'release, and not just a click to
+        // open the popup:
+        id: pressedTimer
+        interval: 400 // Todo: fetch value from style object
+    }
+
+    onPressed: {
+        if (state == "popupClosed") {
+            // Show the popup:
+            pressedTimer.running = true
+            popup.popupOpen = true
+            popup.buttonPressed = true
+        }
+    }
+
+    onReleased: {
+        if (state == "popupOpen" && pressedTimer.running === false) {
+            // Either we have a 'new' click on the popup, or the user has
+            // done a drag'n'release. In either case, the user has done a selection:
+            var mappedPos = mapToItem(listView.contentItem, mouseX, mouseY);
+            var indexAt = listView.indexAt(mappedPos.x, mappedPos.y);
+            if(indexAt != -1)
+                listView.currentIndex = indexAt;
+            popup.popupOpen = false
+        }
+        popup.buttonPressed = false
+    }
+
+    onPositionChanged: {
+        if (state == "popupOpen")
+            popup.highlightItemAt(mouseX, mouseY)
+    }
+
+    states: [
+        State {
+            name: "popupClosed"
+            when: popupFrameLoader.item.opacity === 0;
+            StateChangeScript {
+                script: parent = originalParent;
+            }
+        }
+    ]
+}
+
+
+
+
diff --git a/share/qtcreator/welcomescreen/components/custom/qmldir b/share/qtcreator/welcomescreen/components/custom/qmldir
new file mode 100644 (file)
index 0000000..8da1fd8
--- /dev/null
@@ -0,0 +1,14 @@
+RangeModel 1.0 RangeModel.qml
+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
+Slider 1.0 Slider.qml
+SpinBox 1.0 SpinBox.qml
+TextField 1.0 TextField.qml
+GroupBox 1.0 GroupBox.qml
diff --git a/share/qtcreator/welcomescreen/components/images/folder_new.png b/share/qtcreator/welcomescreen/components/images/folder_new.png
new file mode 100644 (file)
index 0000000..8d8bb9b
Binary files /dev/null and b/share/qtcreator/welcomescreen/components/images/folder_new.png differ
diff --git a/share/qtcreator/welcomescreen/components/qmldir b/share/qtcreator/welcomescreen/components/qmldir
new file mode 100644 (file)
index 0000000..d33a797
--- /dev/null
@@ -0,0 +1,27 @@
+Slider 1.0 Slider.qml
+SpinBox 1.0 SpinBox.qml
+GroupBox 1.0 GroupBox.qml
+Button 1.0 Button.qml
+ToolBar 1.0 ToolBar.qml
+TabFrame 1.0 TabFrame.qml
+TabBar 1.0 TabBar.qml
+Tab 1.0 Tab.qml
+ScrollArea 1.0 ScrollArea.qml
+ScrollBar 1.0 ScrollBar.qml
+ChoiceList 1.0 ChoiceList.qml
+ToolButton 1.0 ToolButton.qml
+TextArea 1.0 TextArea.qml
+TextField 1.0 TextField.qml
+ProgressBar 1.0 ProgressBar.qml
+ButtonRow 1.0 ButtonRow.qml
+ButtonColumn 1.0 ButtonColumn.qml
+SplitterRow 1.0 SplitterRow.qml
+Dial 1.0 Dial.qml
+TableView 1.0 TableView.qml
+CheckBox 1.0 CheckBox.qml
+RadioButton 1.0 RadioButton.qml
+plugin styleplugin plugin
+TableColumn 1.0 TableColumn.qml
+ContextMenu 1.0 ContextMenu.qml
+Menu 1.0 Menu.qml
+MenuItem 1.0 MenuItem.qml
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qdeclarativefolderlistmodel.cpp b/share/qtcreator/welcomescreen/components/styleitem/qdeclarativefolderlistmodel.cpp
new file mode 100644 (file)
index 0000000..89c072b
--- /dev/null
@@ -0,0 +1,488 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![code]
+#include "qdeclarativefolderlistmodel.h"
+#include <QDirModel>
+#include <QDebug>
+#include <qdeclarativecontext.h>
+
+#ifndef QT_NO_DIRMODEL
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeFolderListModelPrivate
+{
+public:
+    QDeclarativeFolderListModelPrivate()
+        : sortField(QDeclarativeFolderListModel::Name), sortReversed(false), count(0) {
+        nameFilters << QLatin1String("*");
+    }
+
+    void updateSorting() {
+        QDir::SortFlags flags = 0;
+        switch(sortField) {
+        case QDeclarativeFolderListModel::Unsorted:
+            flags |= QDir::Unsorted;
+            break;
+        case QDeclarativeFolderListModel::Name:
+            flags |= QDir::Name;
+            break;
+        case QDeclarativeFolderListModel::Time:
+            flags |= QDir::Time;
+            break;
+        case QDeclarativeFolderListModel::Size:
+            flags |= QDir::Size;
+            break;
+        case QDeclarativeFolderListModel::Type:
+            flags |= QDir::Type;
+            break;
+        }
+
+        if (sortReversed)
+            flags |= QDir::Reversed;
+
+        model.setSorting(flags);
+    }
+
+    QDirModel model;
+    QUrl folder;
+    QStringList nameFilters;
+    QModelIndex folderIndex;
+    QDeclarativeFolderListModel::SortField sortField;
+    bool sortReversed;
+    int count;
+};
+
+/*!
+    \qmlclass FolderListModel QDeclarativeFolderListModel
+    \ingroup qml-working-with-data
+    \brief The FolderListModel provides a model of the contents of a file system folder.
+
+    FolderListModel provides access to information about the contents of a folder
+    in the local file system, exposing a list of files to views and other data components.
+
+    \note This type is made available by importing the \c Qt.labs.folderlistmodel module.
+    \e{Elements in the Qt.labs module are not guaranteed to remain compatible
+    in future versions.}
+
+    \bold{import Qt.labs.folderlistmodel 1.0}
+
+    The \l folder property specifies the folder to access. Information about the
+    files and directories in the folder is supplied via the model's interface.
+    Components access names and paths via the following roles:
+
+    \list
+    \o fileName
+    \o filePath
+    \endlist
+
+    Additionally a file entry can be differentiated from a folder entry via the
+    isFolder() method.
+
+    \section1 Filtering
+
+    Various properties can be set to filter the number of files and directories
+    exposed by the model.
+
+    The \l nameFilters property can be set to contain a list of wildcard filters
+    that are applied to names of files and directories, causing only those that
+    match the filters to be exposed.
+
+    Directories can be included or excluded using the \l showDirs property, and
+    navigation directories can also be excluded by setting the \l showDotAndDotDot
+    property to false.
+
+    It is sometimes useful to limit the files and directories exposed to those
+    that the user can access. The \l showOnlyReadable property can be set to
+    enable this feature.
+
+    \section1 Example Usage
+
+    The following example shows a FolderListModel being used to provide a list
+    of QML files in a \l ListView:
+
+    \snippet doc/src/snippets/declarative/folderlistmodel.qml 0
+
+    \section1 Path Separators
+
+    Qt uses "/" as a universal directory separator in the same way that "/" is
+    used as a path separator in URLs. If you always use "/" as a directory
+    separator, Qt will translate your paths to conform to the underlying
+    operating system.
+
+    \sa {QML Data Models}
+*/
+
+QDeclarativeFolderListModel::QDeclarativeFolderListModel(QObject *parent)
+    : QAbstractListModel(parent)
+{
+    QHash<int, QByteArray> roles;
+    roles[FileNameRole] = "fileName";
+    roles[FilePathRole] = "filePath";
+    roles[FileSizeRole] = "fileSize";
+    setRoleNames(roles);
+
+    d = new QDeclarativeFolderListModelPrivate;
+    d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot);
+    connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int))
+            , this, SLOT(inserted(const QModelIndex&,int,int)));
+    connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int))
+            , this, SLOT(removed(const QModelIndex&,int,int)));
+    connect(&d->model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&))
+            , this, SLOT(handleDataChanged(const QModelIndex&,const QModelIndex&)));
+    connect(&d->model, SIGNAL(modelReset()), this, SLOT(refresh()));
+    connect(&d->model, SIGNAL(layoutChanged()), this, SLOT(refresh()));
+}
+
+QDeclarativeFolderListModel::~QDeclarativeFolderListModel()
+{
+    delete d;
+}
+
+QVariant QDeclarativeFolderListModel::data(const QModelIndex &index, int role) const
+{
+    QVariant rv;
+    QModelIndex modelIndex = d->model.index(index.row(), 0, d->folderIndex);
+    if (modelIndex.isValid()) {
+        if (role == FileNameRole)
+            rv = d->model.data(modelIndex, QDirModel::FileNameRole).toString();
+        else if (role == FilePathRole)
+            rv = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString());
+        else if (role == FileSizeRole)
+            rv = d->model.data(d->model.index(index.row(), 1, d->folderIndex), Qt::DisplayRole).toString();
+    }
+    return rv;
+}
+
+/*!
+    \qmlproperty int FolderListModel::count
+
+    Returns the number of items in the current folder that match the
+    filter criteria.
+*/
+int QDeclarativeFolderListModel::rowCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+    return d->count;
+}
+
+/*!
+    \qmlproperty string FolderListModel::folder
+
+    The \a folder property holds a URL for the folder that the model is
+    currently providing.
+
+    The value is a URL expressed as a string, and must be a \c file: or \c qrc:
+    URL, or a relative URL.
+
+    By default, the value is an invalid URL.
+*/
+QUrl QDeclarativeFolderListModel::folder() const
+{
+    return d->folder;
+}
+
+void QDeclarativeFolderListModel::setFolder(const QUrl &folder)
+{
+    if (folder == d->folder)
+        return;
+    QModelIndex index = d->model.index(folder.toLocalFile());
+    if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) {
+
+        d->folder = folder;
+        QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
+        emit folderChanged();
+    }
+}
+
+/*!
+    \qmlproperty url FolderListModel::parentFolder
+
+    Returns the URL of the parent of of the current \l folder.
+*/
+QUrl QDeclarativeFolderListModel::parentFolder() const
+{
+    QString localFile = d->folder.toLocalFile();
+    if (!localFile.isEmpty()) {
+        QDir dir(localFile);
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN)
+        if (dir.isRoot())
+            dir.setPath("");
+        else
+#endif
+            dir.cdUp();
+        localFile = dir.path();
+    } else {
+        int pos = d->folder.path().lastIndexOf(QLatin1Char('/'));
+        if (pos == -1)
+            return QUrl();
+        localFile = d->folder.path().left(pos);
+    }
+    return QUrl::fromLocalFile(localFile);
+}
+
+/*!
+    \qmlproperty list<string> FolderListModel::nameFilters
+
+    The \a nameFilters property contains a list of file name filters.
+    The filters may include the ? and * wildcards.
+
+    The example below filters on PNG and JPEG files:
+
+    \qml
+    FolderListModel {
+        nameFilters: [ "*.png", "*.jpg" ]
+    }
+    \endqml
+
+    \note Directories are not excluded by filters.
+*/
+QStringList QDeclarativeFolderListModel::nameFilters() const
+{
+    return d->nameFilters;
+}
+
+void QDeclarativeFolderListModel::setNameFilters(const QStringList &filters)
+{
+    d->nameFilters = filters;
+    d->model.setNameFilters(d->nameFilters);
+}
+
+void QDeclarativeFolderListModel::classBegin()
+{
+}
+
+void QDeclarativeFolderListModel::componentComplete()
+{
+    if (!d->folder.isValid() || d->folder.toLocalFile().isEmpty() || !QDir().exists(d->folder.toLocalFile()))
+        setFolder(QUrl(QLatin1String("file://")+QDir::currentPath()));
+
+    if (!d->folderIndex.isValid())
+        QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
+}
+
+/*!
+    \qmlproperty enumeration FolderListModel::sortField
+
+    The \a sortField property contains field to use for sorting.  sortField
+    may be one of:
+    \list
+    \o Unsorted - no sorting is applied.  The order is system default.
+    \o Name - sort by filename
+    \o Time - sort by time modified
+    \o Size - sort by file size
+    \o Type - sort by file type (extension)
+    \endlist
+
+    \sa sortReversed
+*/
+QDeclarativeFolderListModel::SortField QDeclarativeFolderListModel::sortField() const
+{
+    return d->sortField;
+}
+
+void QDeclarativeFolderListModel::setSortField(SortField field)
+{
+    if (field != d->sortField) {
+        d->sortField = field;
+        d->updateSorting();
+    }
+}
+
+/*!
+    \qmlproperty bool FolderListModel::sortReversed
+
+    If set to true, reverses the sort order.  The default is false.
+
+    \sa sortField
+*/
+bool QDeclarativeFolderListModel::sortReversed() const
+{
+    return d->sortReversed;
+}
+
+void QDeclarativeFolderListModel::setSortReversed(bool rev)
+{
+    if (rev != d->sortReversed) {
+        d->sortReversed = rev;
+        d->updateSorting();
+    }
+}
+
+/*!
+    \qmlmethod bool FolderListModel::isFolder(int index)
+
+    Returns true if the entry \a index is a folder; otherwise
+    returns false.
+*/
+bool QDeclarativeFolderListModel::isFolder(int index) const
+{
+    if (index != -1) {
+        QModelIndex idx = d->model.index(index, 0, d->folderIndex);
+        if (idx.isValid())
+            return d->model.isDir(idx);
+    }
+    return false;
+}
+
+void QDeclarativeFolderListModel::refresh()
+{
+    d->folderIndex = QModelIndex();
+    if (d->count) {
+        emit beginRemoveRows(QModelIndex(), 0, d->count-1);
+        d->count = 0;
+        emit endRemoveRows();
+    }
+    d->folderIndex = d->model.index(d->folder.toLocalFile());
+    int newcount = d->model.rowCount(d->folderIndex);
+    if (newcount) {
+        emit beginInsertRows(QModelIndex(), 0, newcount-1);
+        d->count = newcount;
+        emit endInsertRows();
+    }
+}
+
+void QDeclarativeFolderListModel::inserted(const QModelIndex &index, int start, int end)
+{
+    if (index == d->folderIndex) {
+        emit beginInsertRows(QModelIndex(), start, end);
+        d->count = d->model.rowCount(d->folderIndex);
+        emit endInsertRows();
+    }
+}
+
+void QDeclarativeFolderListModel::removed(const QModelIndex &index, int start, int end)
+{
+    if (index == d->folderIndex) {
+        emit beginRemoveRows(QModelIndex(), start, end);
+        d->count = d->model.rowCount(d->folderIndex);
+        emit endRemoveRows();
+    }
+}
+
+void QDeclarativeFolderListModel::handleDataChanged(const QModelIndex &start, const QModelIndex &end)
+{
+    if (start.parent() == d->folderIndex)
+        emit dataChanged(index(start.row(),0), index(end.row(),0));
+}
+
+/*!
+    \qmlproperty bool FolderListModel::showDirs
+
+    If true, directories are included in the model; otherwise only files
+    are included.
+
+    By default, this property is true.
+
+    Note that the nameFilters are not applied to directories.
+
+    \sa showDotAndDotDot
+*/
+bool QDeclarativeFolderListModel::showDirs() const
+{
+    return d->model.filter() & QDir::AllDirs;
+}
+
+void  QDeclarativeFolderListModel::setShowDirs(bool on)
+{
+    if (!(d->model.filter() & QDir::AllDirs) == !on)
+        return;
+    if (on)
+        d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives);
+    else
+        d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives));
+}
+
+/*!
+    \qmlproperty bool FolderListModel::showDotAndDotDot
+
+    If true, the "." and ".." directories are included in the model; otherwise
+    they are excluded.
+
+    By default, this property is false.
+
+    \sa showDirs
+*/
+bool QDeclarativeFolderListModel::showDotAndDotDot() const
+{
+    return !(d->model.filter() & QDir::NoDotAndDotDot);
+}
+
+void  QDeclarativeFolderListModel::setShowDotAndDotDot(bool on)
+{
+    if (!(d->model.filter() & QDir::NoDotAndDotDot) == on)
+        return;
+    if (on)
+        d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot);
+    else
+        d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot);
+}
+
+/*!
+    \qmlproperty bool FolderListModel::showOnlyReadable
+
+    If true, only readable files and directories are shown; otherwise all files
+    and directories are shown.
+
+    By default, this property is false.
+
+    \sa showDirs
+*/
+bool QDeclarativeFolderListModel::showOnlyReadable() const
+{
+    return d->model.filter() & QDir::Readable;
+}
+
+void QDeclarativeFolderListModel::setShowOnlyReadable(bool on)
+{
+    if (!(d->model.filter() & QDir::Readable) == !on)
+        return;
+    if (on)
+        d->model.setFilter(d->model.filter() | QDir::Readable);
+    else
+        d->model.setFilter(d->model.filter() & ~QDir::Readable);
+}
+
+//![code]
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRMODEL
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qdeclarativefolderlistmodel.h b/share/qtcreator/welcomescreen/components/styleitem/qdeclarativefolderlistmodel.h
new file mode 100644 (file)
index 0000000..f225a04
--- /dev/null
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEFOLDERLISTMODEL_H
+#define QDECLARATIVEFOLDERLISTMODEL_H
+
+#include <qdeclarative.h>
+#include <QStringList>
+#include <QUrl>
+#include <QAbstractListModel>
+
+#ifndef QT_NO_DIRMODEL
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeContext;
+class QModelIndex;
+
+class QDeclarativeFolderListModelPrivate;
+
+//![class begin]
+class QDeclarativeFolderListModel : public QAbstractListModel, public QDeclarativeParserStatus
+{
+    Q_OBJECT
+    Q_INTERFACES(QDeclarativeParserStatus)
+//![class begin]
+
+//![class props]
+    Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged)
+    Q_PROPERTY(QUrl parentFolder READ parentFolder NOTIFY folderChanged)
+    Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
+    Q_PROPERTY(SortField sortField READ sortField WRITE setSortField)
+    Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed)
+    Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs)
+    Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
+    Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
+    Q_PROPERTY(int count READ count NOTIFY countChanged)
+//![class props]
+
+//![abslistmodel]
+public:
+    QDeclarativeFolderListModel(QObject *parent = 0);
+    ~QDeclarativeFolderListModel();
+
+    enum Roles { FileNameRole = Qt::UserRole+1, FilePathRole = Qt::UserRole+2, FileSizeRole = Qt::UserRole+3 };
+
+    int rowCount(const QModelIndex &parent) const;
+    QVariant data(const QModelIndex &index, int role) const;
+//![abslistmodel]
+
+//![count]
+    int count() const { return rowCount(QModelIndex()); }
+//![count]
+
+//![prop funcs]
+    QUrl folder() const;
+    void setFolder(const QUrl &folder);
+
+    QUrl parentFolder() const;
+
+    QStringList nameFilters() const;
+    void setNameFilters(const QStringList &filters);
+
+    enum SortField { Unsorted, Name, Time, Size, Type };
+    SortField sortField() const;
+    void setSortField(SortField field);
+    Q_ENUMS(SortField)
+
+    bool sortReversed() const;
+    void setSortReversed(bool rev);
+
+    bool showDirs() const;
+    void  setShowDirs(bool);
+    bool showDotAndDotDot() const;
+    void  setShowDotAndDotDot(bool);
+    bool showOnlyReadable() const;
+    void  setShowOnlyReadable(bool);
+//![prop funcs]
+
+//![isfolder]
+    Q_INVOKABLE bool isFolder(int index) const;
+//![isfolder]
+
+//![parserstatus]
+    virtual void classBegin();
+    virtual void componentComplete();
+//![parserstatus]
+
+//![notifier]
+Q_SIGNALS:
+    void folderChanged();
+    void countChanged();
+//![notifier]
+
+//![class end]
+private Q_SLOTS:
+    void refresh();
+    void inserted(const QModelIndex &index, int start, int end);
+    void removed(const QModelIndex &index, int start, int end);
+    void handleDataChanged(const QModelIndex &start, const QModelIndex &end);
+
+private:
+    Q_DISABLE_COPY(QDeclarativeFolderListModel)
+    QDeclarativeFolderListModelPrivate *d;
+};
+//![class end]
+
+QT_END_NAMESPACE
+
+//![qml decl]
+QML_DECLARE_TYPE(QDeclarativeFolderListModel)
+//![qml decl]
+
+QT_END_HEADER
+
+#endif // QT_NO_DIRMODEL
+
+#endif // QDECLARATIVEFOLDERLISTMODEL_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qrangemodel.cpp b/share/qtcreator/welcomescreen/components/styleitem/qrangemodel.cpp
new file mode 100644 (file)
index 0000000..83c106e
--- /dev/null
@@ -0,0 +1,520 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+/*!
+    \class QRangeModel
+    \brief The QRangeModel class, helps users to build components that depend
+           on some value and/or position to be in a certain range previously defined
+
+    With this class, the user sets a value range and a position range, which
+    represent the valid values/positions the model can assume. It is worth telling
+    that the value property always has priority over the position property. A nice use
+    case, would be a Slider implementation with the help of QRangeModel. If the user sets
+    a value range to [0,100], a position range to [50,100] and sets the value
+    to 80, the equivalent position would be 90. After that, if the user decides to
+    resize the slider, the value would be the same, but the knob position would
+    be updated due to the new position range.
+
+    \ingroup qt-components
+*/
+
+#include <QEvent>
+#include <QApplication>
+#include <QGraphicsSceneEvent>
+#include <QDebug>
+
+#ifndef QT_NO_ACCESSIBILITY
+#include <QAccessible>
+#endif
+
+#include "qrangemodel.h"
+#include "qrangemodel_p.h"
+
+QRangeModelPrivate::QRangeModelPrivate(QRangeModel *qq)
+    : q_ptr(qq)
+{
+}
+
+QRangeModelPrivate::~QRangeModelPrivate()
+{
+}
+
+void QRangeModelPrivate::init()
+{
+    minimum = 0;
+    maximum = 99;
+    stepSize = 0;
+    value = 0;
+    pos = 0;
+    posatmin = 0;
+    posatmax = 0;
+    inverted = false;
+}
+
+/*!
+    Calculates the position that is going to be seen outside by the component
+    that is using QRangeModel. It takes into account the \l stepSize,
+    \l positionAtMinimum, \l positionAtMaximum properties
+    and \a position that is passed as parameter.
+*/
+
+qreal QRangeModelPrivate::publicPosition(qreal position) const
+{
+    // Calculate the equivalent stepSize for the position property.
+    const qreal min = effectivePosAtMin();
+    const qreal max = effectivePosAtMax();
+    const qreal valueRange = maximum - minimum;
+    const qreal positionValueRatio = valueRange ? (max - min) / valueRange : 0;
+    const qreal positionStep = stepSize * positionValueRatio;
+
+    if (positionStep == 0)
+        return (min < max) ? qBound(min, position, max) : qBound(max, position, min);
+
+    const int stepSizeMultiplier = (position - min) / positionStep;
+
+    // Test whether value is below minimum range
+    if (stepSizeMultiplier < 0)
+        return min;
+
+    qreal leftEdge = (stepSizeMultiplier * positionStep) + min;
+    qreal rightEdge = ((stepSizeMultiplier + 1) * positionStep) + min;
+
+    if (min < max) {
+        leftEdge = qMin(leftEdge, max);
+        rightEdge = qMin(rightEdge, max);
+    } else {
+        leftEdge = qMax(leftEdge, max);
+        rightEdge = qMax(rightEdge, max);
+    }
+
+    if (qAbs(leftEdge - position) <= qAbs(rightEdge - position))
+        return leftEdge;
+    return rightEdge;
+}
+
+/*!
+    Calculates the value that is going to be seen outside by the component
+    that is using QRangeModel. It takes into account the \l stepSize,
+    \l minimumValue, \l maximumValue properties
+    and \a value that is passed as parameter.
+*/
+
+qreal QRangeModelPrivate::publicValue(qreal value) const
+{
+    // It is important to do value-within-range check this
+    // late (as opposed to during setPosition()). The reason is
+    // QML bindings; a position that is initially invalid because it lays
+    // outside the range, might become valid later if the range changes.
+
+    if (stepSize == 0)
+        return qBound(minimum, value, maximum);
+
+    const int stepSizeMultiplier = (value - minimum) / stepSize;
+
+    // Test whether value is below minimum range
+    if (stepSizeMultiplier < 0)
+        return minimum;
+
+    const qreal leftEdge = qMin(maximum, (stepSizeMultiplier * stepSize) + minimum);
+    const qreal rightEdge = qMin(maximum, ((stepSizeMultiplier + 1) * stepSize) + minimum);
+    const qreal middle = (leftEdge + rightEdge) / 2;
+
+    return (value <= middle) ? leftEdge : rightEdge;
+}
+
+/*!
+    Checks if the \l value or \l position, that is seen by the user, has changed and emits the changed signal if it
+    has changed.
+*/
+
+void QRangeModelPrivate::emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition)
+{
+    Q_Q(QRangeModel);
+
+    // Effective value and position might have changed even in cases when e.g. d->value is
+    // unchanged. This will be the case when operating with values outside range:
+    const qreal newValue = q->value();
+    const qreal newPosition = q->position();
+    if (!qFuzzyCompare(newValue, oldValue))
+        emit q->valueChanged(newValue);
+    if (!qFuzzyCompare(newPosition, oldPosition))
+        emit q->positionChanged(newPosition);
+}
+
+/*!
+    Constructs a QRangeModel with \a parent
+*/
+
+QRangeModel::QRangeModel(QObject *parent)
+    : QObject(parent), d_ptr(new QRangeModelPrivate(this))
+{
+    Q_D(QRangeModel);
+    d->init();
+}
+
+/*!
+    \internal
+    Constructs a QRangeModel with private class pointer \a dd and \a parent
+*/
+
+QRangeModel::QRangeModel(QRangeModelPrivate &dd, QObject *parent)
+    : QObject(parent), d_ptr(&dd)
+{
+    Q_D(QRangeModel);
+    d->init();
+}
+
+/*!
+    Destroys the QRangeModel
+*/
+
+QRangeModel::~QRangeModel()
+{
+    delete d_ptr;
+    d_ptr = 0;
+}
+
+/*!
+    Sets the range of valid positions, that \l position can assume externally, with
+    \a min and \a max.
+    Such range is represented by \l positionAtMinimum and \l positionAtMaximum
+*/
+
+void QRangeModel::setPositionRange(qreal min, qreal max)
+{
+    Q_D(QRangeModel);
+
+    bool emitPosAtMinChanged = !qFuzzyCompare(min, d->posatmin);
+    bool emitPosAtMaxChanged = !qFuzzyCompare(max, d->posatmax);
+
+    if (!(emitPosAtMinChanged || emitPosAtMaxChanged))
+        return;
+
+    const qreal oldPosition = position();
+    d->posatmin = min;
+    d->posatmax = max;
+
+    // When a new positionRange is defined, the position property must be updated based on the value property.
+    // For instance, imagine that you have a valueRange of [0,100] and a position range of [20,100],
+    // if a user set the value to 50, the position would be 60. If this positionRange is updated to [0,100], then
+    // the new position, based on the value (50), will be 50.
+    // If the newPosition is different than the old one, it must be updated, in order to emit
+    // the positionChanged signal.
+    d->pos = d->equivalentPosition(d->value);
+
+    if (emitPosAtMinChanged)
+        emit positionAtMinimumChanged(d->posatmin);
+    if (emitPosAtMaxChanged)
+        emit positionAtMaximumChanged(d->posatmax);
+
+    d->emitValueAndPositionIfChanged(value(), oldPosition);
+}
+/*!
+    Sets the range of valid values, that \l value can assume externally, with
+    \a min and \a max. The range has the following constraint: \a min must be less or equal \a max
+    Such range is represented by \l minimumValue and \l maximumValue
+*/
+
+void QRangeModel::setRange(qreal min, qreal max)
+{
+    Q_D(QRangeModel);
+
+    bool emitMinimumChanged = !qFuzzyCompare(min, d->minimum);
+    bool emitMaximumChanged = !qFuzzyCompare(max, d->maximum);
+
+    if (!(emitMinimumChanged || emitMaximumChanged))
+        return;
+
+    const qreal oldValue = value();
+    const qreal oldPosition = position();
+
+    d->minimum = min;
+    d->maximum = qMax(min, max);
+
+    // Update internal position if it was changed. It can occurs if internal value changes, due to range update
+    d->pos = d->equivalentPosition(d->value);
+
+    if (emitMinimumChanged)
+        emit minimumChanged(d->minimum);
+    if (emitMaximumChanged)
+        emit maximumChanged(d->maximum);
+
+    d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+/*!
+    \property QRangeModel::minimumValue
+    \brief the minimum value that \l value can assume
+
+    This property's default value is 0
+*/
+
+void QRangeModel::setMinimum(qreal min)
+{
+    Q_D(const QRangeModel);
+    setRange(min, d->maximum);
+}
+
+qreal QRangeModel::minimum() const
+{
+    Q_D(const QRangeModel);
+    return d->minimum;
+}
+
+/*!
+    \property QRangeModel::maximumValue
+    \brief the maximum value that \l value can assume
+
+    This property's default value is 99
+*/
+
+void QRangeModel::setMaximum(qreal max)
+{
+    Q_D(const QRangeModel);
+    // if the new maximum value is smaller than
+    // minimum, update minimum too
+    setRange(qMin(d->minimum, max), max);
+}
+
+qreal QRangeModel::maximum() const
+{
+    Q_D(const QRangeModel);
+    return d->maximum;
+}
+
+/*!
+    \property QRangeModel::stepSize
+    \brief the value that is added to the \l value and \l position property
+
+    Example: If a user sets a range of [0,100] and stepSize
+    to 30, the valid values that are going to be seen externally would be: 0, 30, 60, 90, 100.
+*/
+
+void QRangeModel::setStepSize(qreal stepSize)
+{
+    Q_D(QRangeModel);
+
+    stepSize = qMax(qreal(0.0), stepSize);
+    if (qFuzzyCompare(stepSize, d->stepSize))
+        return;
+
+    const qreal oldValue = value();
+    const qreal oldPosition = position();
+    d->stepSize = stepSize;
+
+    emit stepSizeChanged(d->stepSize);
+    d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+qreal QRangeModel::stepSize() const
+{
+    Q_D(const QRangeModel);
+    return d->stepSize;
+}
+
+/*!
+    Returns a valid position, respecting the \l positionAtMinimum,
+    \l positionAtMaximum and the \l stepSize properties.
+    Such calculation is based on the parameter \a value (which is valid externally).
+*/
+
+qreal QRangeModel::positionForValue(qreal value) const
+{
+    Q_D(const QRangeModel);
+
+    const qreal unconstrainedPosition = d->equivalentPosition(value);
+    return d->publicPosition(unconstrainedPosition);
+}
+
+/*!
+    \property QRangeModel::position
+    \brief the current position of the model
+
+    Represents a valid external position, based on the \l positionAtMinimum,
+    \l positionAtMaximum and the \l stepSize properties.
+    The user can set it internally with a position, that is not within the current position range,
+    since it can become valid if the user changes the position range later.
+*/
+
+qreal QRangeModel::position() const
+{
+    Q_D(const QRangeModel);
+
+    // Return the internal position but observe boundaries and
+    // stepSize restrictions.
+    return d->publicPosition(d->pos);
+}
+
+void QRangeModel::setPosition(qreal newPosition)
+{
+    Q_D(QRangeModel);
+
+    if (qFuzzyCompare(newPosition, d->pos))
+        return;
+
+    const qreal oldPosition = position();
+    const qreal oldValue = value();
+
+    // Update position and calculate new value
+    d->pos = newPosition;
+    d->value = d->equivalentValue(d->pos);
+    d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+/*!
+    \property QRangeModel::positionAtMinimum
+    \brief the minimum value that \l position can assume
+
+    This property's default value is 0
+*/
+
+void QRangeModel::setPositionAtMinimum(qreal min)
+{
+    Q_D(QRangeModel);
+    setPositionRange(min, d->posatmax);
+}
+
+qreal QRangeModel::positionAtMinimum() const
+{
+    Q_D(const QRangeModel);
+    return d->posatmin;
+}
+
+/*!
+    \property QRangeModel::positionAtMaximum
+    \brief the maximum value that \l position can assume
+
+    This property's default value is 0
+*/
+
+void QRangeModel::setPositionAtMaximum(qreal max)
+{
+    Q_D(QRangeModel);
+    setPositionRange(d->posatmin, max);
+}
+
+qreal QRangeModel::positionAtMaximum() const
+{
+    Q_D(const QRangeModel);
+    return d->posatmax;
+}
+
+/*!
+    Returns a valid value, respecting the \l minimumValue,
+    \l maximumValue and the \l stepSize properties.
+    Such calculation is based on the parameter \a position (which is valid externally).
+*/
+
+qreal QRangeModel::valueForPosition(qreal position) const
+{
+    Q_D(const QRangeModel);
+
+    const qreal unconstrainedValue = d->equivalentValue(position);
+    return d->publicValue(unconstrainedValue);
+}
+
+/*!
+    \property QRangeModel::value
+    \brief the current value of the model
+
+    Represents a valid external value, based on the \l minimumValue,
+    \l maximumValue and the \l stepSize properties.
+    The user can set it internally with a value, that is not within the current range,
+    since it can become valid if the user changes the range later.
+*/
+
+qreal QRangeModel::value() const
+{
+    Q_D(const QRangeModel);
+
+    // Return internal value but observe boundaries and
+    // stepSize restrictions
+    return d->publicValue(d->value);
+}
+
+void QRangeModel::setValue(qreal newValue)
+{
+    Q_D(QRangeModel);
+
+    if (qFuzzyCompare(newValue, d->value))
+        return;
+
+    const qreal oldValue = value();
+    const qreal oldPosition = position();
+
+    // Update relative value and position
+    d->value = newValue;
+    d->pos = d->equivalentPosition(d->value);
+    d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+/*!
+    \property QRangeModel::inverted
+    \brief the model is inverted or not
+
+    The model can be represented with an inverted behavior, e.g. when \l value assumes
+    the maximum value (represented by \l maximumValue) the \l position will be at its
+    minimum (represented by \l positionAtMinimum).
+*/
+
+void QRangeModel::setInverted(bool inverted)
+{
+    Q_D(QRangeModel);
+    if (inverted == d->inverted)
+        return;
+
+    d->inverted = inverted;
+    emit invertedChanged(d->inverted);
+
+    // After updating the internal value, the position property can change.
+    setPosition(d->equivalentPosition(d->value));
+}
+
+bool QRangeModel::inverted() const
+{
+    Q_D(const QRangeModel);
+    return d->inverted;
+}
+
+/*!
+    Sets the \l value to \l minimumValue.
+*/
+
+void QRangeModel::toMinimum()
+{
+    Q_D(const QRangeModel);
+    setValue(d->minimum);
+}
+
+/*!
+    Sets the \l value to \l maximumValue.
+*/
+
+void QRangeModel::toMaximum()
+{
+    Q_D(const QRangeModel);
+    setValue(d->maximum);
+}
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qrangemodel.h b/share/qtcreator/welcomescreen/components/styleitem/qrangemodel.h
new file mode 100644 (file)
index 0000000..6144281
--- /dev/null
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef QRANGEMODEL_H
+#define QRANGEMODEL_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qgraphicsitem.h>
+#include <QtGui/qabstractslider.h>
+#include <QtDeclarative/qdeclarative.h>
+
+class QRangeModelPrivate;
+
+class QRangeModel : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged USER true)
+    Q_PROPERTY(qreal minimumValue READ minimum WRITE setMinimum NOTIFY minimumChanged)
+    Q_PROPERTY(qreal maximumValue READ maximum WRITE setMaximum NOTIFY maximumChanged)
+    Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged)
+    Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged)
+    Q_PROPERTY(qreal positionAtMinimum READ positionAtMinimum WRITE setPositionAtMinimum NOTIFY positionAtMinimumChanged)
+    Q_PROPERTY(qreal positionAtMaximum READ positionAtMaximum WRITE setPositionAtMaximum NOTIFY positionAtMaximumChanged)
+    Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged)
+
+public:
+    QRangeModel(QObject *parent = 0);
+    virtual ~QRangeModel();
+
+    void setRange(qreal min, qreal max);
+    void setPositionRange(qreal min, qreal max);
+
+    void setStepSize(qreal stepSize);
+    qreal stepSize() const;
+
+    void setMinimum(qreal min);
+    qreal minimum() const;
+
+    void setMaximum(qreal max);
+    qreal maximum() const;
+
+    void setPositionAtMinimum(qreal posAtMin);
+    qreal positionAtMinimum() const;
+
+    void setPositionAtMaximum(qreal posAtMax);
+    qreal positionAtMaximum() const;
+
+    void setInverted(bool inverted);
+    bool inverted() const;
+
+    qreal value() const;
+    qreal position() const;
+
+    Q_INVOKABLE qreal valueForPosition(qreal position) const;
+    Q_INVOKABLE qreal positionForValue(qreal value) const;
+
+public Q_SLOTS:
+    void toMinimum();
+    void toMaximum();
+    void setValue(qreal value);
+    void setPosition(qreal position);
+
+Q_SIGNALS:
+    void valueChanged(qreal value);
+    void positionChanged(qreal position);
+
+    void stepSizeChanged(qreal stepSize);
+
+    void invertedChanged(bool inverted);
+
+    void minimumChanged(qreal min);
+    void maximumChanged(qreal max);
+    void positionAtMinimumChanged(qreal min);
+    void positionAtMaximumChanged(qreal max);
+
+protected:
+    QRangeModel(QRangeModelPrivate &dd, QObject *parent);
+    QRangeModelPrivate* d_ptr;
+
+private:
+    Q_DISABLE_COPY(QRangeModel)
+    Q_DECLARE_PRIVATE(QRangeModel)
+
+};
+
+QML_DECLARE_TYPE(QRangeModel)
+
+#endif // QRANGEMODEL_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qrangemodel_p.h b/share/qtcreator/welcomescreen/components/styleitem/qrangemodel_p.h
new file mode 100644 (file)
index 0000000..cb72cef
--- /dev/null
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef QRANGEMODEL_P_H
+#define QRANGEMODEL_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt Components API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qrangemodel.h"
+
+class QRangeModelPrivate
+{
+    Q_DECLARE_PUBLIC(QRangeModel)
+public:
+    QRangeModelPrivate(QRangeModel *qq);
+    virtual ~QRangeModelPrivate();
+
+    void init();
+
+    qreal posatmin, posatmax;
+    qreal minimum, maximum, stepSize, pos, value;
+
+    uint inverted : 1;
+
+    QRangeModel *q_ptr;
+
+    inline qreal effectivePosAtMin() const {
+        return inverted ? posatmax : posatmin;
+    }
+
+    inline qreal effectivePosAtMax() const {
+        return inverted ? posatmin : posatmax;
+    }
+
+    inline qreal equivalentPosition(qreal value) const {
+        // Return absolute position from absolute value
+        const qreal valueRange = maximum - minimum;
+        if (valueRange == 0)
+            return effectivePosAtMin();
+
+        const qreal scale = (effectivePosAtMax() - effectivePosAtMin()) / valueRange;
+        return (value - minimum) * scale + effectivePosAtMin();
+    }
+
+    inline qreal equivalentValue(qreal pos) const {
+        // Return absolute value from absolute position
+        const qreal posRange = effectivePosAtMax() - effectivePosAtMin();
+        if (posRange == 0)
+            return minimum;
+
+        const qreal scale = (maximum - minimum) / posRange;
+        return (pos - effectivePosAtMin()) * scale + minimum;
+    }
+
+    qreal publicPosition(qreal position) const;
+    qreal publicValue(qreal value) const;
+    void emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition);
+};
+
+#endif // QRANGEMODEL_P_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qstyleitem.cpp b/share/qtcreator/welcomescreen/components/styleitem/qstyleitem.cpp
new file mode 100644 (file)
index 0000000..0e6d942
--- /dev/null
@@ -0,0 +1,1055 @@
+/****************************************************************************
+**
+** 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>
+#include <QtCore/QStringBuilder>
+
+
+QStyleItem::QStyleItem(QDeclarativeItem *parent)
+    : QDeclarativeItem(parent),
+    m_dummywidget(0),
+    m_styleoption(0),
+    m_type(Undefined),
+    m_sunken(false),
+    m_raised(false),
+    m_active(true),
+    m_selected(false),
+    m_focus(false),
+    m_on(false),
+    m_horizontal(true),
+    m_sharedWidget(false),
+    m_minimum(0),
+    m_maximum(100),
+    m_value(0),
+    m_paintMargins(0)
+{
+    setFlag(QGraphicsItem::ItemHasNoContents, false);
+    setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+    setSmooth(true);
+
+    connect(this, SIGNAL(infoChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(onChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(selectedChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(textChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(raisedChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(sunkenChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(hoverChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(maximumChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(minimumChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(valueChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(horizontalChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(focusChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
+    connect(this, SIGNAL(elementTypeChanged()), this, SLOT(updateItem()));
+}
+
+QStyleItem::~QStyleItem()
+{
+    delete m_styleoption;
+    m_styleoption = 0;
+
+    if (!m_sharedWidget) {
+        delete m_dummywidget;
+        m_dummywidget = 0;
+    }
+}
+
+void QStyleItem::initStyleOption()
+{
+    QString type = elementType();
+    if (m_styleoption)
+        m_styleoption->state = 0;
+
+    switch (m_itemType) {
+    case Button: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionButton();
+
+            QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
+            opt->text = text();
+            opt->features = (activeControl() == "default") ?
+                            QStyleOptionButton::DefaultButton :
+                            QStyleOptionButton::None;
+        }
+        break;
+    case ItemRow: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionViewItemV4();
+
+            QStyleOptionViewItemV4 *opt = qstyleoption_cast<QStyleOptionViewItemV4*>(m_styleoption);
+            opt->features = 0;
+            if (activeControl() == "alternate")
+                opt->features |= QStyleOptionViewItemV2::Alternate;
+        }
+        break;
+
+    case Splitter: {
+            if (!m_styleoption) {
+                m_styleoption = new QStyleOption;
+            }
+        }
+        break;
+
+    case Item: {
+            if (!m_styleoption) {
+                m_styleoption = new QStyleOptionViewItemV4();
+            }
+            QStyleOptionViewItemV4 *opt = qstyleoption_cast<QStyleOptionViewItemV4*>(m_styleoption);
+            opt->features = QStyleOptionViewItemV4::HasDisplay;
+            opt->text = text();
+            opt->textElideMode = Qt::ElideRight;
+            QPalette pal = m_styleoption->palette;
+            pal.setBrush(QPalette::Base, Qt::NoBrush);
+            m_styleoption->palette = pal;
+        }
+        break;
+    case Header: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionHeader();
+
+            QStyleOptionHeader *opt = qstyleoption_cast<QStyleOptionHeader*>(m_styleoption);
+            opt->text = text();
+            opt->sortIndicator = activeControl() == "down" ?
+                                 QStyleOptionHeader::SortDown
+                                     : activeControl() == "up" ?
+                                     QStyleOptionHeader::SortUp : QStyleOptionHeader::None;
+            if (activeControl() == QLatin1String("beginning"))
+                opt->position = QStyleOptionHeader::Beginning;
+            else if (activeControl() == QLatin1String("end"))
+                opt->position = QStyleOptionHeader::End;
+            else if (activeControl() == QLatin1String("only"))
+                opt->position = QStyleOptionHeader::OnlyOneSection;
+            else
+                opt->position = QStyleOptionHeader::Middle;
+
+        }
+        break;
+    case ToolButton :{
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionToolButton();
+
+            QStyleOptionToolButton *opt =
+                    qstyleoption_cast<QStyleOptionToolButton*>(m_styleoption);
+            opt->subControls = QStyle::SC_ToolButton;
+            opt->state |= QStyle::State_AutoRaise;
+            opt->activeSubControls = QStyle::SC_ToolButton;
+        }
+        break;
+    case ToolBar: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionToolBar();
+        }
+        break;
+    case Tab: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionTabV3();
+
+            QStyleOptionTabV3 *opt =
+                    qstyleoption_cast<QStyleOptionTabV3*>(m_styleoption);
+            opt->text = text();
+            opt->shape = info() == "South" ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
+            if (activeControl() == QLatin1String("beginning"))
+                opt->position = QStyleOptionTabV3::Beginning;
+            else if (activeControl() == QLatin1String("end"))
+                opt->position = QStyleOptionTabV3::End;
+            else if (activeControl() == QLatin1String("only"))
+                opt->position = QStyleOptionTabV3::OnlyOneTab;
+            else
+                opt->position = QStyleOptionTabV3::Middle;
+
+        } break;
+
+    case Menu: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionMenuItem();
+        }
+        break;
+    case Frame: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionFrameV3();
+
+            QStyleOptionFrameV3 *opt = qstyleoption_cast<QStyleOptionFrameV3*>(m_styleoption);
+            opt->frameShape = QFrame::StyledPanel;
+            opt->lineWidth = 1;
+            opt->midLineWidth = 1;
+        }
+        break;
+    case TabFrame: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionTabWidgetFrameV2();
+            QStyleOptionTabWidgetFrameV2 *opt = qstyleoption_cast<QStyleOptionTabWidgetFrameV2*>(m_styleoption);
+            opt->shape = (info() == "South") ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
+            if (minimum())
+                opt->selectedTabRect = QRect(value(), 0, minimum(), height());
+            opt->tabBarSize = QSize(minimum() , height());
+            // oxygen style needs this hack
+            opt->leftCornerWidgetSize = QSize(value(), 0);
+        }
+        break;
+    case MenuItem:
+    case ComboBoxItem:
+        {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionMenuItem();
+
+            QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption);
+            opt->checked = false;
+            opt->text = text();
+            opt->palette = widget()->palette();
+        }
+        break;
+    case CheckBox:
+    case RadioButton:
+        {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionButton();
+
+            QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
+            if (!on())
+                opt->state |= QStyle::State_Off;
+            opt->text = text();
+        }
+        break;
+    case Edit: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionFrameV3();
+
+            QStyleOptionFrameV3 *opt = qstyleoption_cast<QStyleOptionFrameV3*>(m_styleoption);
+            opt->lineWidth = 1; // this must be non-zero
+        }
+        break;
+    case ComboBox :{
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionComboBox();
+            QStyleOptionComboBox *opt = qstyleoption_cast<QStyleOptionComboBox*>(m_styleoption);
+            opt->currentText = text();
+        }
+        break;
+    case SpinBox: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionSpinBox();
+
+            QStyleOptionSpinBox *opt = qstyleoption_cast<QStyleOptionSpinBox*>(m_styleoption);
+            opt->frame = true;
+            if (value() & 0x1)
+                opt->activeSubControls = QStyle::SC_SpinBoxUp;
+            else if (value() & (1<<1))
+                opt->activeSubControls = QStyle::SC_SpinBoxDown;
+            opt->subControls = QStyle::SC_All;
+            opt->stepEnabled = 0;
+            if (value() & (1<<2))
+                opt->stepEnabled |= QAbstractSpinBox::StepUpEnabled;
+            if (value() & (1<<3))
+                opt->stepEnabled |= QAbstractSpinBox::StepDownEnabled;
+        }
+        break;
+    case Slider:
+    case Dial:
+        {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionSlider();
+
+            QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption);
+            opt->minimum = minimum();
+            opt->maximum = maximum();
+            // ### fixme - workaround for KDE inverted dial
+            opt->sliderPosition = value();
+            opt->tickInterval = opt->maximum != opt->minimum ? 1200 / (opt->maximum - opt->minimum) : 0;
+            if (style() == QLatin1String("oxygen") && type == QLatin1String("dial"))
+                opt->sliderValue  = maximum() - value();
+            else
+                opt->sliderValue = value();
+            opt->subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
+            opt->tickPosition = (activeControl() == "below") ?
+                                QSlider::TicksBelow : (activeControl() == "above" ?
+                                                       QSlider::TicksAbove:
+                                                       QSlider::NoTicks);
+            if (opt->tickPosition != QSlider::NoTicks)
+                opt->subControls |= QStyle::SC_SliderTickmarks;
+
+            opt->activeSubControls = QStyle::SC_None;
+        }
+        break;
+    case ProgressBar: {
+            if (QProgressBar *bar= qobject_cast<QProgressBar*>(widget())){
+                bar->setMaximum(maximum());
+                bar->setMinimum(minimum());
+                if (maximum() != minimum())
+                    bar->setValue(1);
+            }
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionProgressBarV2();
+
+            QStyleOptionProgressBarV2 *opt = qstyleoption_cast<QStyleOptionProgressBarV2*>(m_styleoption);
+            opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
+            opt->minimum = minimum();
+            opt->maximum = maximum();
+            opt->progress = value();
+        }
+        break;
+    case GroupBox: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionGroupBox();
+
+            QStyleOptionGroupBox *opt = qstyleoption_cast<QStyleOptionGroupBox*>(m_styleoption);
+            opt->text = text();
+            opt->lineWidth = 1;
+            opt->subControls = QStyle::SC_GroupBoxLabel;
+            if (sunken()) // Qt draws an ugly line here so I ignore it
+                opt->subControls |= QStyle::SC_GroupBoxFrame;
+            else
+                opt->features |= QStyleOptionFrameV2::Flat;
+            if (activeControl() == "checkbox")
+                opt->subControls |= QStyle::SC_GroupBoxCheckBox;
+
+            if (QGroupBox *group= qobject_cast<QGroupBox*>(widget())) {
+                group->setTitle(text());
+                group->setCheckable(opt->subControls & QStyle::SC_GroupBoxCheckBox);
+            }
+        }
+        break;
+    case ScrollBar: {
+            if (!m_styleoption)
+                m_styleoption = new QStyleOptionSlider();
+
+            QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption);
+            opt->minimum = minimum();
+            opt->maximum = maximum();
+            opt->pageStep = horizontal() ? width() : height();
+            opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
+            opt->sliderPosition = value();
+            opt->sliderValue = value();
+            opt->activeSubControls = (activeControl() == QLatin1String("up"))
+                                     ? QStyle::SC_ScrollBarSubLine :
+                                     (activeControl() == QLatin1String("down")) ?
+                                     QStyle::SC_ScrollBarAddLine:
+                                     QStyle::SC_ScrollBarSlider;
+
+            opt->sliderValue = value();
+            opt->subControls = QStyle::SC_All;
+
+            QScrollBar *bar = qobject_cast<QScrollBar *>(widget());
+            bar->setMaximum(maximum());
+            bar->setMinimum(minimum());
+            bar->setValue(value());
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!m_styleoption)
+        m_styleoption = new QStyleOption();
+
+    m_styleoption->rect = QRect(m_paintMargins, m_paintMargins, width() - 2* m_paintMargins, height() - 2 * m_paintMargins);
+
+    if (isEnabled())
+        m_styleoption->state |= QStyle::State_Enabled;
+    if (m_active)
+        m_styleoption->state |= QStyle::State_Active;
+    if (m_sunken)
+        m_styleoption->state |= QStyle::State_Sunken;
+    if (m_raised)
+        m_styleoption->state |= QStyle::State_Raised;
+    if (m_selected)
+        m_styleoption->state |= QStyle::State_Selected;
+    if (m_focus)
+        m_styleoption->state |= QStyle::State_HasFocus;
+    if (m_on)
+        m_styleoption->state |= QStyle::State_On;
+    if (m_hover)
+        m_styleoption->state |= QStyle::State_MouseOver;
+    if (m_horizontal)
+        m_styleoption->state |= QStyle::State_Horizontal;
+
+    if (widget()) {
+        widget()->ensurePolished();
+        if (type == QLatin1String("tab") && style() != QLatin1String("mac")) {
+            // Some styles actually check the beginning and end position
+            // using widget geometry, so we have to trick it
+            widget()->setGeometry(0, 0, width(), height());
+            if (activeControl() != "beginning")
+                m_styleoption->rect.translate(1, 0); // Don't position at start of widget
+            if (activeControl() != "end")
+                widget()->resize(200, height());
+        }
+#ifdef Q_WS_WIN
+        else widget()->resize(width(), height());
+#endif
+
+        widget()->setEnabled(isEnabled());
+        m_styleoption->fontMetrics = widget()->fontMetrics();
+        if (!m_styleoption->palette.resolve())
+            m_styleoption->palette = widget()->palette();
+        if (m_hint.contains("mac.mini")) {
+            widget()->setAttribute(Qt::WA_MacMiniSize);
+        } else if (m_hint.contains("mac.small")) {
+            widget()->setAttribute(Qt::WA_MacSmallSize);
+        }
+    }
+}
+
+/*
+ *   Property style
+ *
+ *   Returns a simplified style name.
+ *
+ *   QMacStyle = "mac"
+ *   QWindowsXPStyle = "windowsxp"
+ *   QPlastiqueStyle = "plastique"
+ */
+
+QString QStyleItem::style() const
+{
+    QString style = qApp->style()->metaObject()->className();
+    style = style.toLower();
+    if (style.contains(QLatin1String("oxygen")))
+        return QLatin1String("oxygen");
+    if (style.startsWith(QLatin1Char('q')))
+        style = style.right(style.length() - 1);
+    if (style.endsWith("style"))
+        style = style.left(style.length() - 5);
+    return style.toLower();
+}
+
+QString QStyleItem::hitTest(int px, int py)
+{
+    QStyle::SubControl subcontrol = QStyle::SC_All;
+    initStyleOption();
+    switch (m_itemType) {
+    case SpinBox :{
+            subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_SpinBox,
+                                                              qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                                              QPoint(px,py), 0);
+            if (subcontrol == QStyle::SC_SpinBoxUp)
+                return "up";
+            else if (subcontrol == QStyle::SC_SpinBoxDown)
+                return "down";
+
+        }
+        break;
+
+    case Slider: {
+            subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_Slider,
+                                                              qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                                              QPoint(px,py), 0);
+            if (subcontrol == QStyle::SC_SliderHandle)
+                return "handle";
+
+        }
+        break;
+    case ScrollBar: {
+            subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_ScrollBar,
+                                                              qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                                              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";
+        }
+        break;
+    default:
+        break;
+    }
+    return "none";
+}
+
+QSize QStyleItem::sizeFromContents(int width, int height)
+{
+    initStyleOption();
+
+    QSize size;
+    switch (m_itemType) {
+    case CheckBox:
+        size =  qApp->style()->sizeFromContents(QStyle::CT_CheckBox, m_styleoption, QSize(width,height), widget());
+        break;
+    case ToolButton:
+        size = qApp->style()->sizeFromContents(QStyle::CT_ToolButton, m_styleoption, QSize(width,height), widget());
+        break;
+    case Button:
+        size = qApp->style()->sizeFromContents(QStyle::CT_PushButton, m_styleoption, QSize(width,height), widget());
+        break;
+    case Tab:
+        size = qApp->style()->sizeFromContents(QStyle::CT_TabBarTab, m_styleoption, QSize(width,height), widget());
+        break;
+    case ComboBox:
+        size = qApp->style()->sizeFromContents(QStyle::CT_ComboBox, m_styleoption, QSize(width,height), widget());
+        break;
+    case SpinBox:
+        size = qApp->style()->sizeFromContents(QStyle::CT_SpinBox, m_styleoption, QSize(width,height), widget());
+        break;
+    case Slider:
+        size = qApp->style()->sizeFromContents(QStyle::CT_Slider, m_styleoption, QSize(width,height), widget());
+        break;
+    case ProgressBar:
+        size = qApp->style()->sizeFromContents(QStyle::CT_ProgressBar, m_styleoption, QSize(width,height), widget());
+        break;
+    case Edit:
+        size = qApp->style()->sizeFromContents(QStyle::CT_LineEdit, m_styleoption, QSize(width,height), widget());
+        break;
+    case GroupBox:
+        size = qApp->style()->sizeFromContents(QStyle::CT_GroupBox, m_styleoption, QSize(width,height), widget());
+        break;
+    case Header:
+        size = qApp->style()->sizeFromContents(QStyle::CT_HeaderSection, m_styleoption, QSize(width,height), widget());
+#ifdef Q_WS_MAC
+        if (style() =="mac")
+            size.setHeight(15);
+#endif
+        break;
+    case ItemRow:
+    case Item: //fall through
+        size = qApp->style()->sizeFromContents(QStyle::CT_ItemViewItem, m_styleoption, QSize(width,height), widget());
+        break;
+    default:
+        break;
+    }
+
+#ifdef Q_WS_MAC
+    // ### hack - With even heights, the text baseline is off on mac
+    if (size.height() %2 == 0)
+        size.setHeight(size.height() + 1);
+#endif
+    return size;
+}
+
+
+int QStyleItem::pixelMetric(const QString &metric)
+{
+
+    if (metric == "scrollbarExtent")
+        return qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, widget());
+    else if (metric == "defaultframewidth")
+        return qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, widget());
+    else if (metric == "taboverlap")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 , widget());
+    else if (metric == "tabbaseoverlap")
+#ifdef Q_WS_WIN
+        // On windows the tabbar paintmargin extends the overlap by one pixels
+        return 1 + qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, 0 , widget());
+#else
+    return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, 0 , widget());
+#endif
+    else if (metric == "tabhspace")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarTabHSpace, 0 , widget());
+    else if (metric == "tabvspace")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarTabVSpace, 0 , widget());
+    else if (metric == "tabbaseheight")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0 , widget());
+    else if (metric == "tabvshift")
+        return qApp->style()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, 0 , widget());
+    else if (metric == "menuhmargin")
+        return qApp->style()->pixelMetric(QStyle::PM_MenuHMargin, 0 , widget());
+    else if (metric == "menuvmargin")
+        return qApp->style()->pixelMetric(QStyle::PM_MenuVMargin, 0 , widget());
+    else if (metric == "menupanelwidth")
+        return qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0 , widget());
+    else if (metric == "splitterwidth")
+        return qApp->style()->pixelMetric(QStyle::PM_SplitterWidth, 0 , widget());
+    // This metric is incorrectly negative on oxygen
+    else if (metric == "scrollbarspacing")
+        return abs(qApp->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, 0 , widget()));
+    return 0;
+}
+
+QVariant QStyleItem::styleHint(const QString &metric)
+{
+    initStyleOption();
+    if (metric == "comboboxpopup") {
+        return qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, m_styleoption);
+    } else if (metric == "highlightedTextColor") {
+        if (widget())
+            return widget()->palette().highlightedText().color().name();
+        return qApp->palette().highlightedText().color().name();
+    } else if (metric == "textColor") {
+        if (widget())
+            return widget()->palette().text().color().name();
+        return qApp->palette().text().color().name();
+    } else if (metric == "focuswidget") {
+        return qApp->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget);
+
+    } else if (metric == "tabbaralignment") {
+        int result = qApp->style()->styleHint(QStyle::SH_TabBar_Alignment);
+        if (result == Qt::AlignCenter)
+            return "center";
+        return "left";
+
+    } else if (metric == "framearoundcontents")
+        return qApp->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents);
+    return 0;
+}
+
+void QStyleItem::setCursor(const QString &str)
+{
+    if (m_cursor != str) {
+        m_cursor = str;
+        if (m_cursor == "sizehorcursor")
+            QDeclarativeItem::setCursor(Qt::SizeHorCursor);
+        else if (m_cursor == "sizevercursor")
+            QDeclarativeItem::setCursor(Qt::SizeVerCursor);
+        else if (m_cursor == "sizeallcursor")
+            QDeclarativeItem::setCursor(Qt::SizeAllCursor);
+        else if (m_cursor == "splithcursor")
+            QDeclarativeItem::setCursor(Qt::SplitHCursor);
+        else if (m_cursor == "splitvcursor")
+            QDeclarativeItem::setCursor(Qt::SplitVCursor);
+        else if (m_cursor == "wait")
+            QDeclarativeItem::setCursor(Qt::WaitCursor);
+        else if (m_cursor == "pointinghandcursor")
+            QDeclarativeItem::setCursor(Qt::PointingHandCursor);
+        emit cursorChanged();
+    }
+}
+
+void QStyleItem::setElementType(const QString &str)
+{
+    if (m_type == str)
+        return;
+
+    m_type = str;
+
+    emit elementTypeChanged();
+
+    if (m_dummywidget && !m_sharedWidget) {
+        delete m_dummywidget;
+        m_dummywidget = 0;
+    }
+
+    if (m_styleoption) {
+        delete m_styleoption;
+        m_styleoption = 0;
+    }
+
+    // Only enable visible if the widget can animate
+    bool visible = false;
+    if (str == "menu" || str == "menuitem") {
+        // Since these are used by the delegate, it makes no
+        // sense to re-create them per item
+        static QWidget *menu = new QMenu();
+        m_sharedWidget = true;
+        m_dummywidget = menu;
+        m_itemType = (str == "menu") ? Menu : MenuItem;
+    } else if (str == "item" || str == "itemrow" || str == "header") {
+        // Since these are used by the delegate, it makes no
+        // sense to re-create them per item
+        static QTreeView *menu = new QTreeView();
+        menu->setAttribute(Qt::WA_MacMiniSize);
+        m_sharedWidget = true;
+        if (str == "header") {
+            m_dummywidget = menu->header();
+            if (style() == "mac") { // The default qt font seems to big
+                QFont font = m_dummywidget->font();
+                font.setPointSize(11);
+                m_dummywidget->setFont(font);
+            }
+            m_itemType = Header;
+        } else {
+            m_dummywidget = menu;
+            m_itemType = (str == "item") ? Item : ItemRow;
+        }
+    } else if (str == "groupbox") {
+        // Since these are used by the delegate, it makes no
+        // sense to re-create them per item
+        static QGroupBox *group = new QGroupBox();
+        m_sharedWidget = true;
+        m_dummywidget = group;
+        m_itemType = GroupBox;
+    } else if (str == "tabframe" || str == "tab") {
+        static QTabWidget *tabframe = new QTabWidget();
+        m_sharedWidget = true;
+        if (str == "tab") {
+            m_dummywidget = tabframe->findChild<QTabBar*>();
+            m_itemType = Tab;
+        } else {
+            m_dummywidget = tabframe;
+            m_itemType = TabFrame;
+        }
+    } else if (str == "comboboxitem")  {
+        // Gtk uses qobject cast, hence we need to separate this from menuitem
+        // On mac, we temporarily use the menu item because it has more accurate
+        // palette.
+#ifdef Q_WS_MAC
+        static QMenu *combo = new QMenu();
+#else
+        static QComboBox *combo = new QComboBox();
+#endif
+        m_sharedWidget = true;
+        m_dummywidget = combo;
+        m_itemType = ComboBoxItem;
+    } else if (str == "toolbar") {
+        static QToolBar *tb = 0;
+        if (!tb) {
+            QMainWindow *mw = new QMainWindow();
+            tb = new QToolBar(mw);
+        }
+        m_dummywidget = tb;
+        m_itemType = ToolBar;
+    } else if (str == "toolbutton") {
+        static QToolButton *tb = 0;
+        static QToolBar *bar = 0;
+        // KDE animations are too broken with these widgets
+        if (style() != QLatin1String("oxygen")) {
+            if (!tb) {
+                bar = new QToolBar(0);
+                tb = new QToolButton(bar);
+            }
+        }
+        m_sharedWidget = true;
+        m_dummywidget = tb;
+        m_itemType = ToolButton;
+    } else if (str == "slider") {
+        static QSlider *slider = new QSlider();
+        m_sharedWidget = true;
+        m_dummywidget = slider;
+        m_itemType = Slider;
+    } else if (str == "frame") {
+        static QFrame *frame = new QFrame();
+        m_sharedWidget = true;
+        m_dummywidget = frame;
+        m_itemType = Frame;
+    } else if (str == "combobox") {
+        m_dummywidget = new QComboBox();
+        visible = true;
+        m_itemType = ComboBox;
+    } else if (str == "splitter") {
+        visible = true;
+        m_itemType = Splitter;
+    } else if (str == "progressbar") {
+        m_dummywidget = new QProgressBar();
+        visible = true;
+        m_itemType = ProgressBar;
+    } else if (str == "button") {
+        m_dummywidget = new QPushButton();
+        visible = true;
+        m_itemType = Button;
+    } else if (str == "checkbox") {
+        m_dummywidget = new QCheckBox();
+        visible = true;
+        m_itemType = CheckBox;
+    } else if (str == "radiobutton") {
+        m_dummywidget = new QRadioButton();
+        visible = true;
+        m_itemType = RadioButton;
+    } else if (str == "edit") {
+        m_dummywidget = new QLineEdit();
+        visible = true;
+        m_itemType = Edit;
+    } else if (str == "spinbox") {
+#ifndef Q_WS_WIN // Vista spinbox is currently not working due to grabwidget
+        m_dummywidget = new QSpinBox();
+        visible = true;
+#endif
+        m_itemType = SpinBox;
+    } else if (str == "scrollbar") {
+        m_dummywidget = new QScrollBar();
+        visible = true;
+        m_itemType = ScrollBar;
+    } else if (str == "widget") {
+        m_itemType = Widget;
+    } else if (str == "focusframe") {
+        m_itemType = FocusFrame;
+    } else if (str == "dial") {
+        m_itemType = Dial;
+    }
+    if (m_dummywidget) {
+        m_dummywidget->installEventFilter(this);
+        m_dummywidget->setAttribute(Qt::WA_QuitOnClose, false); // dont keep app open
+        m_dummywidget->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+        m_dummywidget->winId();
+#ifdef Q_WS_MAC
+        m_dummywidget->setGeometry(-1000, 0, 10,10);
+        m_dummywidget->setVisible(visible); // Mac require us to set the visibility before this
+#endif
+        m_dummywidget->setAttribute(Qt::WA_DontShowOnScreen);
+        m_dummywidget->setVisible(visible);
+    }
+}
+
+bool QStyleItem::eventFilter(QObject *o, QEvent *e) {
+    if (e->type() == QEvent::Paint) {
+        updateItem();
+        return true;
+    }
+    return QObject::eventFilter(o, e);
+}
+
+void QStyleItem::showToolTip(const QString &str)
+{
+    QPointF scene = mapToScene(width() - 20, 0);
+    QPoint global = qApp->focusWidget()->mapToGlobal(scene.toPoint());
+    QToolTip::showText(QPoint(global.x(), global.y()), str);
+}
+
+QRect QStyleItem::subControlRect(const QString &subcontrolString)
+{
+    QStyle::SubControl subcontrol = QStyle::SC_None;
+    initStyleOption();
+    switch (m_itemType) {
+    case SpinBox:
+        {
+            QStyle::ComplexControl control = QStyle::CC_SpinBox;
+            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,
+                                                 qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                                 subcontrol, widget());
+
+        }
+        break;
+    case Slider:
+        {
+            QStyle::ComplexControl control = QStyle::CC_Slider;
+            if (subcontrolString == QLatin1String("handle"))
+                subcontrol = QStyle::SC_SliderHandle;
+            else if (subcontrolString == QLatin1String("groove"))
+                subcontrol = QStyle::SC_SliderGroove;
+            return qApp->style()->subControlRect(control,
+                                                 qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                                 subcontrol, widget());
+
+        }
+        break;
+    case ScrollBar:
+        {
+            QStyle::ComplexControl control = QStyle::CC_ScrollBar;
+            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,
+                                                 qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                                 subcontrol, widget());
+        }
+        break;
+    default:
+        break;
+    }
+    return QRect();
+}
+
+void QStyleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+    if (width() < 1 || height() <1)
+        return;
+
+    initStyleOption();
+
+    if (widget()) {
+        painter->save();
+        painter->setFont(widget()->font());
+        painter->translate(-m_styleoption->rect.left() + m_paintMargins, 0);
+    }
+
+    switch (m_itemType) {
+    case Button:
+        qApp->style()->drawControl(QStyle::CE_PushButton, m_styleoption, painter, widget());
+        break;
+    case ItemRow :{
+            QPixmap pixmap;
+            // Only draw through style once
+            const QString pmKey = QLatin1Literal("itemrow") % QString::number(m_styleoption->state,16) % activeControl();
+            if (!QPixmapCache::find(pmKey, pixmap) || pixmap.width() < width() || height() != pixmap.height()) {
+                int newSize = width();
+                pixmap = QPixmap(newSize, height());
+                pixmap.fill(Qt::transparent);
+                QPainter pixpainter(&pixmap);
+                qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, m_styleoption, &pixpainter, widget());
+                if (!qApp->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected) && selected())
+                    pixpainter.fillRect(m_styleoption->rect, m_styleoption->palette.highlight());
+                QPixmapCache::insert(pmKey, pixmap);
+            }
+            painter->drawPixmap(0, 0, pixmap);
+        }
+        break;
+    case Item:
+        qApp->style()->drawControl(QStyle::CE_ItemViewItem, m_styleoption, painter, widget());
+        break;
+    case Header:
+        widget()->resize(m_styleoption->rect.size()); // macstyle explicitly uses the widget height
+        qApp->style()->drawControl(QStyle::CE_Header, m_styleoption, painter, widget());
+        break;
+    case ToolButton:
+        qApp->style()->drawComplexControl(QStyle::CC_ToolButton, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter, widget());
+        break;
+    case Tab:
+        qApp->style()->drawControl(QStyle::CE_TabBarTab, m_styleoption, painter, widget());
+        break;
+    case Frame:
+        qApp->style()->drawControl(QStyle::CE_ShapedFrame, m_styleoption, painter, widget());
+        break;
+    case FocusFrame:
+        qApp->style()->drawControl(QStyle::CE_FocusFrame, m_styleoption, painter, widget());
+        break;
+    case TabFrame:
+        qApp->style()->drawPrimitive(QStyle::PE_FrameTabWidget, m_styleoption, painter, widget());
+        break;
+    case MenuItem:
+    case ComboBoxItem: // fall through
+        qApp->style()->drawControl(QStyle::CE_MenuItem, m_styleoption, painter, widget());
+        break;
+    case CheckBox:
+        qApp->style()->drawControl(QStyle::CE_CheckBox, m_styleoption, painter, widget());
+        break;
+    case RadioButton:
+        qApp->style()->drawControl(QStyle::CE_RadioButton, m_styleoption, painter, widget());
+        break;
+    case Edit:
+        qApp->style()->drawPrimitive(QStyle::PE_PanelLineEdit, m_styleoption, painter, widget());
+        break;
+    case Widget:
+        qApp->style()->drawPrimitive(QStyle::PE_Widget, m_styleoption, painter, widget());
+        break;
+    case Splitter:
+        qApp->style()->drawControl(QStyle::CE_Splitter, m_styleoption, painter, widget());
+        break;
+    case ComboBox:
+        qApp->style()->drawComplexControl(QStyle::CC_ComboBox,
+                                          qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                          painter, widget());
+        qApp->style()->drawControl(QStyle::CE_ComboBoxLabel, m_styleoption, painter, widget());
+        break;
+    case SpinBox:
+        qApp->style()->drawComplexControl(QStyle::CC_SpinBox,
+                                          qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                          painter, widget());
+        break;
+    case Slider:
+        qApp->style()->drawComplexControl(QStyle::CC_Slider,
+                                          qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                          painter, widget());
+        break;
+    case Dial:
+        qApp->style()->drawComplexControl(QStyle::CC_Dial,
+                                          qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+                                          painter, widget());
+        break;
+    case ProgressBar:
+        qApp->style()->drawControl(QStyle::CE_ProgressBar, m_styleoption, painter, widget());
+        break;
+    case ToolBar:
+        qApp->style()->drawControl(QStyle::CE_ToolBar, m_styleoption, painter, widget());
+        break;
+    case GroupBox:
+        qApp->style()->drawComplexControl(QStyle::CC_GroupBox, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter, widget());
+        break;
+    case ScrollBar:
+        qApp->style()->drawComplexControl(QStyle::CC_ScrollBar, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter, widget());
+        break;
+    case Menu: {
+            if (QMenu *menu = qobject_cast<QMenu*>(widget())) {
+                m_styleoption->palette = menu->palette();
+            }
+            QStyleHintReturnMask val;
+            qApp->style()->styleHint(QStyle::SH_Menu_Mask, m_styleoption, widget(), &val);
+            painter->save();
+            painter->setClipRegion(val.region);
+            painter->fillRect(m_styleoption->rect, m_styleoption->palette.window());
+            painter->restore();
+            qApp->style()->drawPrimitive(QStyle::PE_PanelMenu, m_styleoption, painter, widget());
+
+            QStyleOptionFrame frame;
+            frame.lineWidth = qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth);
+            frame.midLineWidth = 0;
+            frame.rect = m_styleoption->rect;
+            qApp->style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, painter, widget());
+        }
+        break;
+    default:
+        break;
+    }
+    if (widget())
+        painter->restore();
+}
+
+int QStyleItem::textWidth(const QString &text)
+{
+    if (widget())
+        return widget()->fontMetrics().boundingRect(text).width();
+    return qApp->fontMetrics().boundingRect(text).width();
+}
+
+int QStyleItem::fontHeight()
+{
+    if (widget())
+        return widget()->fontMetrics().height();
+    return qApp->fontMetrics().height();
+}
+
+QString QStyleItem::fontFamily()
+{
+    if (widget())
+        return widget()->font().family();
+    return qApp->font().family();
+}
+
+double QStyleItem::fontPointSize()
+{
+    if (widget())
+        return widget()->font().pointSizeF();
+    return qApp->font().pointSizeF();
+}
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qstyleitem.h b/share/qtcreator/welcomescreen/components/styleitem/qstyleitem.h
new file mode 100644 (file)
index 0000000..1b9f9c8
--- /dev/null
@@ -0,0 +1,229 @@
+/****************************************************************************
+**
+** 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>
+
+class QStyleItem: public QDeclarativeItem
+{
+    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 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)
+    Q_PROPERTY( QString info READ info WRITE setInfo NOTIFY infoChanged)
+    Q_PROPERTY( QString style READ style NOTIFY styleChanged)
+    Q_PROPERTY( QString hint READ hint WRITE setHint NOTIFY hintChanged)
+    Q_PROPERTY( QString cursor READ cursor WRITE setCursor NOTIFY cursorChanged)
+
+    // 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)
+    Q_PROPERTY( int paintMargins READ paintMargins WRITE setPaintMargins NOTIFY paintMarginsChanged)
+
+    Q_PROPERTY( QString fontFamily READ fontFamily)
+    Q_PROPERTY( double fontPointSize READ fontPointSize)
+    Q_PROPERTY( int fontHeight READ fontHeight NOTIFY fontHeightChanged)
+
+public:
+    enum Type {
+        Undefined,
+        Button,
+        RadioButton,
+        CheckBox,
+        ComboBox,
+        ComboBoxItem,
+        Dial,
+        ToolBar,
+        ToolButton,
+        Tab,
+        TabFrame,
+        Frame,
+        FocusFrame,
+        SpinBox,
+        Slider,
+        ScrollBar,
+        ProgressBar,
+        Edit,
+        GroupBox,
+        Header,
+        Item,
+        ItemRow,
+        Splitter,
+        Menu,
+        MenuItem,
+        Widget
+    };
+
+    QStyleItem(QDeclarativeItem *parent = 0);
+    ~QStyleItem();
+
+    void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+    bool sunken() const { return m_sunken; }
+    bool raised() const { return m_raised; }
+    bool active() const { return m_active; }
+    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; }
+    int paintMargins() const { return m_paintMargins; }
+
+    QString elementType() const { return m_type; }
+    QString text() const { return m_text; }
+    QString cursor() const { return m_cursor; }
+    QString activeControl() const { return m_activeControl; }
+    QString info() const { return m_info; }
+    QString hint() const { return m_hint; }
+    QString style() const;
+
+    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 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 setPaintMargins(int value) {
+    Q_UNUSED(value)
+#ifdef Q_WS_WIN //only vista style needs this hack
+        if (m_paintMargins!= value) {m_paintMargins = value;}
+#endif
+    }
+    void setCursor(const QString &str);
+    void setElementType(const QString &str);
+    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();}}
+    void setInfo(const QString &str) { if (m_info != str) {m_info = str; emit infoChanged();}}
+    void setHint(const QString &str) { if (m_hint != str) {m_hint= str; emit hintChanged();}}
+
+    bool eventFilter(QObject *, QEvent *);
+    virtual void initStyleOption ();
+    QWidget *widget(){ return m_dummywidget; }
+
+    int fontHeight();
+    QString fontFamily();
+    double fontPointSize();
+
+
+public Q_SLOTS:
+    int pixelMetric(const QString&);
+    QVariant styleHint(const QString&);
+    QSize sizeFromContents(int width, int height);
+    void updateItem(){update();}
+    QString hitTest(int x, int y);
+    QRect subControlRect(const QString &subcontrolString);
+    void showToolTip(const QString &str);
+    int textWidth(const QString &);
+
+Q_SIGNALS:
+    void elementTypeChanged();
+    void textChanged();
+    void sunkenChanged();
+    void raisedChanged();
+    void activeChanged();
+    void selectedChanged();
+    void focusChanged();
+    void onChanged();
+    void hoverChanged();
+    void horizontalChanged();
+    void minimumChanged();
+    void maximumChanged();
+    void valueChanged();
+    void activeControlChanged();
+    void infoChanged();
+    void styleChanged();
+    void paintMarginsChanged();
+    void hintChanged();
+    void cursorChanged();
+    void fontHeightChanged();
+
+protected:
+    QWidget *m_dummywidget;
+    QStyleOption *m_styleoption;
+    Type m_itemType;
+
+    QString m_type;
+    QString m_cursor;
+    QString m_text;
+    QString m_activeControl;
+    QString m_info;
+    QString m_hint;
+
+    bool m_sunken;
+    bool m_raised;
+    bool m_active;
+    bool m_selected;
+    bool m_focus;
+    bool m_hover;
+    bool m_on;
+    bool m_horizontal;
+    bool m_sharedWidget;
+
+    int m_minimum;
+    int m_maximum;
+    int m_value;
+    int m_paintMargins;
+};
+
+#endif //STYLEWRAPPER_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qstyleplugin.cpp b/share/qtcreator/welcomescreen/components/styleitem/qstyleplugin.cpp
new file mode 100644 (file)
index 0000000..2015f0e
--- /dev/null
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** 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 "qrangemodel.h"
+#include "qtmenu.h"
+#include "qtmenubar.h"
+#include "qtmenuitem.h"
+#include "qwheelarea.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)
+    {
+        Q_UNUSED(requestedSize);
+        Q_UNUSED(size);
+        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)
+{
+    qDebug() << "register" << uri;
+    qmlRegisterType<QStyleItem>(uri, 1, 0, "QStyleItem");
+    qmlRegisterType<QRangeModel>(uri, 1, 0, "RangeModel");
+    qmlRegisterType<QGraphicsDropShadowEffect>(uri, 1, 0, "DropShadow");
+    qmlRegisterType<QDeclarativeFolderListModel>(uri, 1, 0, "FileSystemModel");
+    qmlRegisterType<QWheelArea>(uri, 1, 0, "WheelArea");
+    qmlRegisterType<QtMenu>(uri, 1, 0, "MenuBase");
+    qmlRegisterType<QtMenuBar>(uri, 1, 0, "MenuBarBase");
+    qmlRegisterType<QtMenuItem>(uri, 1, 0, "MenuItemBase");
+}
+
+void StylePlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)
+{
+    Q_UNUSED(uri);
+    engine->addImageProvider("desktoptheme", new DesktopIconProvider);
+}
+
+Q_EXPORT_PLUGIN2(styleplugin, StylePlugin)
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qstyleplugin.h b/share/qtcreator/welcomescreen/components/styleitem/qstyleplugin.h
new file mode 100644 (file)
index 0000000..648add7
--- /dev/null
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** 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>
+#include <QFileSystemModel>
+#include "qdeclarativefolderlistmodel.h"
+
+
+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/share/qtcreator/welcomescreen/components/styleitem/qtmenu.cpp b/share/qtcreator/welcomescreen/components/styleitem/qtmenu.cpp
new file mode 100644 (file)
index 0000000..e832f98
--- /dev/null
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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.
+**
+****************************************************************************/
+
+#include "qtmenu.h"
+#include "qdebug.h"
+#include <qapplication.h>
+
+QtMenu::QtMenu(QObject *parent)
+    : QObject(parent)
+{
+    m_menu = new QMenu(0);
+}
+
+QtMenu::~QtMenu()
+{
+    delete m_menu;
+}
+
+void QtMenu::setTitle(const QString &title)
+{
+
+}
+
+QString QtMenu::title() const
+{
+
+}
+
+QDeclarativeListProperty<QtMenuItem> QtMenu::menuItems()
+{
+    return QDeclarativeListProperty<QtMenuItem>(this, m_menuItems);
+}
+
+void QtMenu::showPopup(qreal x, qreal y)
+{
+    m_menu->clear();
+    foreach (QtMenuItem *item, m_menuItems) {
+        QAction *action = new QAction(item->text(), m_menu);
+        connect(action, SIGNAL(triggered()), item, SIGNAL(selected()));
+        m_menu->insertAction(0, action);
+    }
+
+    // x,y are in view coordinates, QMenu expects screen coordinates
+    // ### activeWindow hack
+    QPoint screenPosition = QApplication::activeWindow()->mapToGlobal(QPoint(x, y));
+
+    m_menu->popup(screenPosition);
+}
+
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qtmenu.h b/share/qtcreator/welcomescreen/components/styleitem/qtmenu.h
new file mode 100644 (file)
index 0000000..9e17db3
--- /dev/null
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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.
+**
+****************************************************************************/
+
+#ifndef QTMLMENU_H
+#define QTMLMENU_H
+
+#include <QtGui/qmenu.h>
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/QDeclarativeListProperty>
+#include "qtmenuitem.h"
+class QtMenu : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QString title READ title WRITE setTitle)
+    Q_PROPERTY(QDeclarativeListProperty<QtMenuItem> menuItems READ menuItems)
+     Q_CLASSINFO("DefaultProperty", "menuItems")
+public:
+    QtMenu(QObject *parent = 0);
+    virtual ~QtMenu();
+
+    void setTitle(const QString &title);
+    QString title() const;
+    QDeclarativeListProperty<QtMenuItem> menuItems();
+    Q_INVOKABLE void showPopup(qreal x, qreal y);
+Q_SIGNALS:
+    void selected();
+private:
+    QString m_title;
+    QWidget *dummy;
+    QMenu *m_menu;
+    QList<QtMenuItem *> m_menuItems;
+};
+
+QML_DECLARE_TYPE(QtMenu)
+
+#endif // QTMLMENU_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qtmenubar.cpp b/share/qtcreator/welcomescreen/components/styleitem/qtmenubar.cpp
new file mode 100644 (file)
index 0000000..7257795
--- /dev/null
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 "qtmenubar.h"
+
+#include <QtGui/QMenu>
+
+QtMenuBar::QtMenuBar(QDeclarativeItem *parent)
+    : QDeclarativeItem(parent)
+{
+    setFlag(QGraphicsItem::ItemHasNoContents, false);
+}
+
+QtMenuBar::~QtMenuBar()
+{
+}
+
+QDeclarativeListProperty<QtMenu> QtMenuBar::menus()
+{
+    return QDeclarativeListProperty<QtMenu>(this, m_menus);
+}
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qtmenubar.h b/share/qtcreator/welcomescreen/components/styleitem/qtmenubar.h
new file mode 100644 (file)
index 0000000..4c402b8
--- /dev/null
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 QTMENUBAR_H
+#define QTMENUBAR_H
+
+#include <QDeclarativeItem>
+#include <QtGui>
+
+#include "qtmenu.h"
+
+class QtMenuBar: public QDeclarativeItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QDeclarativeListProperty<QtMenu> menus READ menus)
+public:
+    QtMenuBar(QDeclarativeItem *parent = 0);
+    ~QtMenuBar();
+
+    QDeclarativeListProperty<QtMenu> menus();
+
+    //void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+private:
+    QList<QtMenu *> m_menus;
+};
+
+#endif //QTMENUBAR_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qtmenuitem.cpp b/share/qtcreator/welcomescreen/components/styleitem/qtmenuitem.cpp
new file mode 100644 (file)
index 0000000..8769990
--- /dev/null
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 "qtmenuitem.h"
+
+QtMenuItem::QtMenuItem(QObject *parent)
+    : QObject(parent)
+{
+
+}
+
+QtMenuItem::~QtMenuItem()
+{
+}
+
+void QtMenuItem::setText(const QString &text)
+{
+    m_text = text;
+}
+
+QString QtMenuItem::text()
+{
+    return m_text;
+}
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qtmenuitem.h b/share/qtcreator/welcomescreen/components/styleitem/qtmenuitem.h
new file mode 100644 (file)
index 0000000..7c4a1d4
--- /dev/null
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 QTMENUITEM_H
+#define QTMENUITEM_H
+
+#include <QtCore/QObject>
+
+class QtMenuItem: public QObject
+{
+    Q_PROPERTY(QString text READ text WRITE setText);
+
+    Q_OBJECT
+public:
+    QtMenuItem(QObject *parent = 0);
+    ~QtMenuItem();
+
+    void setText(const QString &text);
+    QString text();
+
+Q_SIGNALS:
+    void selected();
+
+private:
+    QString m_text;
+};
+
+#endif //QTMENUITEM_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qwheelarea.cpp b/share/qtcreator/welcomescreen/components/styleitem/qwheelarea.cpp
new file mode 100644 (file)
index 0000000..1a7ae9e
--- /dev/null
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** 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 "qwheelarea.h"
+
+
+QWheelArea::QWheelArea(QDeclarativeItem *parent)
+    : QDeclarativeItem(parent),
+      _horizontalMinimumValue(0),
+      _horizontalMaximumValue(0),
+      _verticalMinimumValue(0),
+      _verticalMaximumValue(0),
+      _horizontalValue(0),
+      _verticalValue(0),
+      _verticalDelta(0),
+      _horizontalDelta(0)
+{}
+
+QWheelArea::~QWheelArea() {}
+
+bool QWheelArea::event (QEvent * e) {
+    switch(e->type()) {
+    case QEvent::GraphicsSceneWheel: {
+        QGraphicsSceneWheelEvent *we = static_cast<QGraphicsSceneWheelEvent*>(e);
+        if(we) {
+            switch(we->orientation()) {
+                case Qt::Horizontal:
+                    setHorizontalDelta(we->delta());
+                    break;
+                case Qt::Vertical:
+                    setVerticalDelta(we->delta());
+            }
+            return true;
+        }
+    }
+    case QEvent::Wheel: {
+        QWheelEvent *we = static_cast<QWheelEvent*>(e);
+        if(we) {
+            switch(we->orientation()) {
+                case Qt::Horizontal:
+                    setHorizontalDelta(we->delta());
+
+                    break;
+                case Qt::Vertical:
+                    setVerticalDelta(we->delta());
+
+            }
+            return true;
+        }
+    }
+    default: break;
+    }
+    return QDeclarativeItem::event(e);
+}
+
+void QWheelArea::setHorizontalMinimumValue(qreal min)
+{
+    _horizontalMinimumValue = min;
+}
+
+qreal QWheelArea::horizontalMinimumValue() const
+{
+    return _horizontalMinimumValue;
+}
+
+void QWheelArea::setHorizontalMaximumValue(qreal max)
+{
+    _horizontalMaximumValue = max;
+}
+qreal QWheelArea::horizontalMaximumValue() const
+{
+    return _horizontalMaximumValue;
+}
+
+void QWheelArea::setVerticalMinimumValue(qreal min)
+{
+    _verticalMinimumValue = min;
+}
+
+qreal QWheelArea::verticalMinimumValue() const
+{
+    return _verticalMinimumValue;
+}
+
+void QWheelArea::setVerticalMaximumValue(qreal max)
+{
+    _verticalMaximumValue = max;
+}
+
+qreal QWheelArea::verticalMaximumValue() const
+{
+    return _verticalMaximumValue;
+}
+
+void QWheelArea::setHorizontalValue(qreal val)
+{
+    if (val > _horizontalMaximumValue)
+       _horizontalValue = _horizontalMaximumValue;
+    else if (val < _horizontalMinimumValue)
+        _horizontalValue = _horizontalMinimumValue;
+    else
+        _horizontalValue = val;
+    emit(horizontalValueChanged());
+}
+
+qreal QWheelArea::horizontalValue() const
+{
+    return _horizontalValue;
+}
+
+void QWheelArea::setVerticalValue(qreal val)
+{
+    if (val > _verticalMaximumValue)
+       _verticalValue = _verticalMaximumValue;
+    else if (val < _verticalMinimumValue)
+        _verticalValue = _verticalMinimumValue;
+    else
+        _verticalValue = val;
+    emit(verticalValueChanged());
+}
+
+qreal QWheelArea::verticalValue() const
+{
+    return _verticalValue;
+}
+
+void QWheelArea::setVerticalDelta(qreal d)
+{
+    _verticalDelta = d/15;
+    setVerticalValue(_verticalValue - _verticalDelta);
+    emit(verticalWheelMoved());
+}
+
+qreal QWheelArea::verticalDelta() const
+{
+    return _verticalDelta;
+}
+
+void QWheelArea::setHorizontalDelta(qreal d)
+{
+    _horizontalDelta = d/15;
+    setHorizontalValue(_horizontalValue - _horizontalDelta);
+    emit(horizontalWheelMoved());
+}
+
+qreal QWheelArea::horizontalDelta() const
+{
+    return _horizontalDelta;
+}
diff --git a/share/qtcreator/welcomescreen/components/styleitem/qwheelarea.h b/share/qtcreator/welcomescreen/components/styleitem/qwheelarea.h
new file mode 100644 (file)
index 0000000..f1d7016
--- /dev/null
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef QWHEELAREA_H
+#define QWHEELAREA_H
+
+
+#include <QtCore/qobject.h>
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/qdeclarativeitem.h>
+#include <QtCore/qcoreevent.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qgraphicssceneevent.h>
+
+class QWheelArea : public QDeclarativeItem
+{
+    Q_OBJECT
+    Q_PROPERTY(qreal verticalDelta READ verticalDelta WRITE setVerticalDelta NOTIFY verticalWheelMoved)
+    Q_PROPERTY(qreal horizontalDelta READ horizontalDelta WRITE setHorizontalDelta NOTIFY horizontalWheelMoved)
+    Q_PROPERTY(qreal horizontalMinimumValue READ horizontalMinimumValue WRITE setHorizontalMinimumValue)
+    Q_PROPERTY(qreal horizontalMaximumValue READ horizontalMaximumValue WRITE setHorizontalMaximumValue)
+    Q_PROPERTY(qreal verticalMinimumValue READ verticalMinimumValue WRITE setVerticalMinimumValue)
+    Q_PROPERTY(qreal verticalMaximumValue READ verticalMaximumValue WRITE setVerticalMaximumValue)
+    Q_PROPERTY(qreal horizontalValue READ horizontalValue WRITE setHorizontalValue)
+    Q_PROPERTY(qreal verticalValue READ verticalValue WRITE setVerticalValue)
+
+
+public:
+    QWheelArea(QDeclarativeItem *parent = 0);
+
+    virtual ~QWheelArea();
+
+    virtual bool event (QEvent * e);
+
+    void setHorizontalMinimumValue(qreal min);
+    qreal horizontalMinimumValue() const;
+
+    void setHorizontalMaximumValue(qreal min);
+    qreal horizontalMaximumValue() const;
+
+    void setVerticalMinimumValue(qreal min);
+    qreal verticalMinimumValue() const;
+
+    void setVerticalMaximumValue(qreal min);
+    qreal verticalMaximumValue() const;
+
+    void setHorizontalValue(qreal val);
+    qreal horizontalValue() const;
+
+    void setVerticalValue(qreal val);
+    qreal verticalValue() const;
+
+    void setVerticalDelta(qreal d);
+    qreal verticalDelta() const;
+
+    void setHorizontalDelta(qreal d);
+    qreal horizontalDelta() const;
+
+Q_SIGNALS:
+    void verticalValueChanged();
+    void horizontalValueChanged();
+    void verticalWheelMoved();
+    void horizontalWheelMoved();
+
+private:
+    qreal _horizontalMinimumValue;
+    qreal _horizontalMaximumValue;
+    qreal _verticalMinimumValue;
+    qreal _verticalMaximumValue;
+    qreal _horizontalValue;
+    qreal _verticalValue;
+    qreal _verticalDelta;
+    qreal _horizontalDelta;
+
+    Q_DISABLE_COPY(QWheelArea)
+};
+
+QML_DECLARE_TYPE(QWheelArea)
+
+
+#endif // QWHEELAREA_H
diff --git a/share/qtcreator/welcomescreen/components/styleitem/styleitem.pro b/share/qtcreator/welcomescreen/components/styleitem/styleitem.pro
new file mode 100644 (file)
index 0000000..25f403a
--- /dev/null
@@ -0,0 +1,78 @@
+TEMPLATE = lib
+CONFIG += qt plugin
+QT += declarative
+QT += script
+TARGET  = styleplugin
+include(../../../../../qtcreator.pri)
+DESTDIR = $$IDE_DATA_PATH/welcomescreen/components/plugin
+OBJECTS_DIR = tmp
+MOC_DIR = tmp
+
+HEADERS += qtmenu.h \
+           qtmenubar.h \
+           qtmenuitem.h \
+           qrangemodel_p.h \
+           qrangemodel.h \
+           qstyleplugin.h \
+           qdeclarativefolderlistmodel.h \
+           qstyleitem.h \
+           qwheelarea.h
+
+SOURCES += qtmenu.cpp \
+           qtmenubar.cpp \
+           qtmenuitem.cpp \
+           qrangemodel.cpp \
+          qstyleplugin.cpp \
+           qdeclarativefolderlistmodel.cpp \
+           qstyleitem.cpp \
+           qwheelarea.cpp
+           
+
+OTHER_FILES += \
+    ../gallery.qml \
+    ../widgets/Tab.qml \
+    ../widgets/TabBar.qml \
+    ../widgets/TabFrame.qml \
+    ../Button.qml \
+    ../ButtonRow.qml \
+    ../CheckBox.qml \
+    ../ChoiceList.qml \
+    ../components.pro \
+    ../ContextMenu.qml \
+    ../Dial.qml \
+    ../Frame.qml \
+    ../GroupBox.qml \
+    ../Menu.qml \
+    ../ProgressBar.qml \
+    ../RadioButton.qml \
+    ../ScrollArea.qml \
+    ../ScrollBar.qml \
+    ../Slider.qml \
+    ../SpinBox.qml \
+    ../Switch.qml \
+    ../Tab.qml \
+    ../TableView.qml \
+    ../TabBar.qml \
+    ../TabFrame.qml \
+    ../TextArea.qml \
+    ../TextField.qml \
+    ../TextScrollArea.qml \
+    ../ToolBar.qml \
+    ../ToolButton.qml \
+    ../custom/BasicButton.qml \
+    ../custom/BusyIndicator.qml \
+    ../custom/Button.qml \
+    ../custom/ButtonColumn.qml \
+    ../custom/ButtonGroup.js \
+    ../custom/ButtonRow.qml \
+    ../custom/CheckBox.qml \
+    ../custom/ChoiceList.qml \
+    ../custom/ProgressBar.qml \
+    ../custom/Slider.qml \
+    ../custom/SpinBox.qml \
+    ../custom/TextField.qml \
+    ../../examples/Browser.qml \
+    ../../examples/Panel.qml \
+    ../../examples/ModelView.qml \
+    ../../examples/Gallery.qml
diff --git a/share/qtcreator/welcomescreen/develop.qml b/share/qtcreator/welcomescreen/develop.qml
new file mode 100644 (file)
index 0000000..7473c78
--- /dev/null
@@ -0,0 +1,28 @@
+import QtQuick 1.0
+import "widgets"
+import "components" as Components
+
+Item {
+    id: root
+
+    Components.ScrollArea {
+        id: scrollArea
+        anchors.fill: parent
+        Item {
+            height: Math.max(recentSessions.height, recentProjects.height)
+            width: root.width-40
+            RecentSessions {
+                id: recentSessions
+                x: 10
+                width: parent.width / 2 - 10
+            }
+            RecentProjects {
+                id: recentProjects
+                x: parent.width / 2 + 10
+                width: parent.width / 2 - 10
+            }
+        }
+    }
+}
+
+
diff --git a/share/qtcreator/welcomescreen/examples_fallback.xml b/share/qtcreator/welcomescreen/examples_fallback.xml
new file mode 100644 (file)
index 0000000..3a0a8dc
--- /dev/null
@@ -0,0 +1,858 @@
+<?xml version="1.0" encoding="utf-8"?>
+<instructionals module="Qt">
+ <demos>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-samegame-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-declarative-samegame.html" projectPath="./declarative/samegame/declarative/samegame.qmlproject" name="SameGame">
+   <description><![CDATA[This demo shows how to write a 'Same Game' game in QML, using Javascript for all the game logic.]]></description>
+   <tags>demo,declarative,samegame,qml,qt quick</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-flickr-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-declarative-flickr.html" projectPath="./declarative/flickr/declarative/flickr.qmlproject" name="Flickr Client">
+   <description><![CDATA[This demo shows how to write a mobile Flickr browser application in QML.]]></description>
+   <tags>demo,declarative,flickr,qml,qt quick</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/affine-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-affine.html" projectPath="./affine/affine.pro" name="Affine Transformations">
+   <description><![CDATA[In this demo we show Qt's ability to perform affine transformations on painting operations.]]></description>
+   <tags>demo,affine</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/composition-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-composition.html" projectPath="./composition/composition.pro" name="Composition Modes">
+   <description><![CDATA[This demo shows some of the more advanced composition modes supported by Qt.]]></description>
+   <tags>demo,composition</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/gradients-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-gradients.html" projectPath="./gradients/gradients.pro" name="Gradients">
+   <description><![CDATA[In this demo we show the various types of gradients that can be used in Qt.]]></description>
+   <tags>demo,gradients</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/pathstroke-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-pathstroke.html" projectPath="./pathstroke/pathstroke.pro" name="Path Stroking">
+   <description><![CDATA[In this demo we show some of the various types of pens that can be used in Qt.]]></description>
+   <tags>demo,pathstroke</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/textedit-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-textedit.html" projectPath="./textedit/textedit.pro" name="Text Edit">
+   <description><![CDATA[The Text Edit demonstration shows Qt's rich text editing facilities in action, providing an example document for you to experiment with.]]></description>
+   <tags>demo,textedit</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/chip-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-chip.html" projectPath="./chip/chip.pro" name="40000 Chips">
+   <description><![CDATA[This demo shows how to visualize a huge scene with 40000 chip items using Graphics View. It also shows Graphics View's powerful navigation and interaction features, allowing you to zoom and rotate each of four views independently, and you can select and move items around the scene.]]></description>
+   <tags>demo,chip</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/embeddeddialogs-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-embeddeddialogs.html" projectPath="./embeddeddialogs/embeddeddialogs.pro" name="Embedded Dialogs">
+   <description><![CDATA[This example shows how to embed standard dialogs into Graphics View. It also shows how you can customize the proxy class and add window shadows.]]></description>
+   <tags>demo,embeddeddialogs</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/interview-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-interview.html" projectPath="./interview/interview.pro" name="Interview">
+   <description><![CDATA[The Interview demonstration explores the flexibility and scalability of the model/view framework by presenting an infinitely deep data structure using a model and three different types of view.]]></description>
+   <tags>demo,interview</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-rssnews-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-declarative-rssnews.html" projectPath="./declarative/rssnews/declarative/rssnews.qmlproject" name="Rss Client">
+   <description><![CDATA[This demo shows how to write a RSS news reader in QML.]]></description>
+   <tags>demo,declarative,rssnews,qml,qt quick</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-twitter-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-declarative-twitter.html" projectPath="./declarative/twitter/declarative/twitter.qmlproject" name="Twitter Client">
+   <description><![CDATA[This demo shows how to write a mobile Twitter search client in QML. Use it to see what people think about Qt Quick!]]></description>
+   <tags>demo,declarative,twitter,qml,qt quick</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/browser-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-browser.html" projectPath="./browser/browser.pro" name="Browser">
+   <description><![CDATA[The Web Browser demonstration shows Qt's WebKit module in action, providing a little Web browser application.]]></description>
+   <tags>demo,browser</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/qmediaplayer-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-qmediaplayer.html" projectPath="./qmediaplayer/qmediaplayer.pro" name="Media Player">
+   <description><![CDATA[The Media Player demonstration shows how <tt>Phonon</tt> can be used in Qt applications to handle audio and video playback.]]></description>
+   <tags>demo,qmediaplayer,phonon</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/boxes-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-boxes.html" projectPath="./boxes/boxes.pro" name="Boxes">
+   <description><![CDATA[This demo shows Qt's ability to combine advanced OpenGL rendering with the the <tt>Graphics View Framework</tt>.]]></description>
+   <tags>demo,boxes,graphics view framework</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/sub-attaq-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-sub-attaq.html" projectPath="./sub-attaq/sub-attaq.pro" name="Sub-attaq">
+   <description><![CDATA[This demo shows Qt's ability to combine <tt>the animation framework</tt> and <tt>the state machine framework</tt> to create a game.]]></description>
+   <tags>demo,sub-attaq,the animation framework,the state machine framework</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/spectrum-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-spectrum.html" projectPath="./spectrum/spectrum.pro" name="Spectrum Analyzer">
+   <description><![CDATA[The Spectrum Analyzer demo shows how the <tt>QtMultimedia Module</tt> can be used in Qt applications to capture and then play back an audio stream.]]></description>
+   <tags>demo,spectrum,qtmultimedia module</tags>
+  </demo>
+  <demo imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-declarative-minehunt.html" projectPath="./declarative/minehunt/declarative/minehunt.pro" name="Minehunt">
+   <description><![CDATA[This demo shows how to create a simple Minehunt game, using QML for the UI and C++ for the game logic.]]></description>
+   <tags>demo,declarative,minehunt</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/deform-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-deform.html" projectPath="./deform/deform.pro" name="Vector Deformation">
+   <description><![CDATA[This demo shows how to use advanced vector techniques to draw text using a <tt>QPainterPath</tt>.]]></description>
+   <tags>demo,deform,qpainterpath</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/books-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-books.html" projectPath="./books/books.pro" name="Books">
+   <description><![CDATA[The Books demonstration shows how Qt's SQL classes can be used with the model/view framework to create rich user interfaces for information stored in a database.]]></description>
+   <tags>demo,books</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/mainwindow-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-mainwindow.html" projectPath="./mainwindow/mainwindow.pro" name="Main Window">
+   <description><![CDATA[The Main Window demonstration shows Qt's extensive support for tool bars, dock windows, menus, and other standard application features.]]></description>
+   <tags>demo,mainwindow</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/spreadsheet-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-spreadsheet.html" projectPath="./spreadsheet/spreadsheet.pro" name="Spreadsheet">
+   <description><![CDATA[The Spreadsheet demonstration shows how a table view can be used to create a simple spreadsheet application. Custom delegates are used to render different types of data in distinctive colors.]]></description>
+   <tags>demo,spreadsheet</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/sqlbrowser-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-sqlbrowser.html" projectPath="./sqlbrowser/sqlbrowser.pro" name="SQL Browser">
+   <description><![CDATA[The SQL Browser demonstration shows how a data browser can be used to visualize the results of SQL statements on a live database.]]></description>
+   <tags>demo,sqlbrowser</tags>
+  </demo>
+  <demo imageUrl="qthelp://com.trolltech.qt/qdoc/images/arthurplugin-demo.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/demos-arthurplugin.html" projectPath="./arthurplugin/arthurplugin.pro" name="Arthur Plugin">
+   <description><![CDATA[In this demo we demonstrate the abilities of Qt's painting system in combination with <i>Qt Designer</i>'s custom widget plugin facilities.]]></description>
+   <tags>demo,arthurplugin</tags>
+  </demo>
+ </demos>
+ <examples>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/animatedtiles-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/animation-animatedtiles.html" projectPath="animation/animatedtiles/animatedtiles.pro" name="Animated Tiles">
+   <description><![CDATA[The Animated Tiles example animates items in a graphics scene.]]></description>
+   <tags>example,animatedtiles,animation</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/appchooser-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/animation-appchooser.html" projectPath="animation/appchooser/appchooser.pro" name="Appchooser">
+   <description><![CDATA[The Application Chooser example shows how to use the Qt state machine and the animation framework to select between applications.]]></description>
+   <tags>example,appchooser,animation</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/easing-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/animation-easing.html" projectPath="animation/easing/easing.pro" name="Easing Curves">
+   <description><![CDATA[The Easing Curves example shows how to use easing curves to control the speed of an animation.]]></description>
+   <tags>example,easing,animation</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/moveblocks-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/animation-moveblocks.html" projectPath="animation/moveblocks/moveblocks.pro" name="Moving Blocks">
+   <description><![CDATA[The Move Blocks example shows how to animate items in a <tt>QGraphicsScene</tt> using a <tt>QStateMachine</tt> with a custom transition.]]></description>
+   <tags>example,moveblocks,animation,qgraphicsscene,qstatemachine</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/states-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/animation-states.html" projectPath="animation/states/states.pro" name="States">
+   <description><![CDATA[The States example shows how to use the Qt state machine to play animations.]]></description>
+   <tags>example,states,animation</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/stickman-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/animation-stickman.html" projectPath="animation/stickman/stickman.pro" name="Stickman">
+   <description><![CDATA[The Stickman example shows how to animate transitions in a state machine to implement key frame animations.]]></description>
+   <tags>example,stickman,animation</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/qtconcurrent-map.html" projectPath="qtconcurrent/map/map.pro" name="Map">
+   <description><![CDATA[The <tt>QtConcurrent</tt> Map example shows how to use the synchronous (blocking) <tt>QtConcurrent</tt> API to scale a collection of images.]]></description>
+   <tags>example,map,qtconcurrent,qtconcurrent,qtconcurrent</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/qtconcurrent-progressdialog.html" projectPath="qtconcurrent/progressdialog/progressdialog.pro" name="Progress Dialog">
+   <description><![CDATA[The <tt>QtConcurrent</tt> Progress Dialog example shows how to use the <tt>QFutureWatcher</tt> class to monitor the progress of a long-running operation.]]></description>
+   <tags>example,progressdialog,qtconcurrent,qtconcurrent,qfuturewatcher</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/qtconcurrent-runfunction.html" projectPath="qtconcurrent/runfunction/runfunction.pro" name="Run Function">
+   <description><![CDATA[The <tt>QtConcurrent</tt> Run Function example shows how to apply concurrency to a standard function, using <tt>QFuture</tt> instances to retrieve return values at a later time.]]></description>
+   <tags>example,runfunction,qtconcurrent,qtconcurrent,qfuture</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/qtconcurrent-wordcount.html" projectPath="qtconcurrent/wordcount/wordcount.pro" name="Word Count">
+   <description><![CDATA[The <tt>QtConcurrent</tt> Word Count example demonstrates the use of the map-reduce algorithm when applied to the problem of counting words in a collection of files.]]></description>
+   <tags>example,wordcount,qtconcurrent,qtconcurrent</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-dynamicscene-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-toys-dynamicscene.html" projectPath="declarative/toys/dynamicscene/dynamicscene.qmlproject" name="Dynamic Scene">
+   <description><![CDATA[This example presents an interactive drag-and-drop scene. It demonstrates how to use QML's <tt>Dynamic Object Creation</tt> support to dynamically create and destroy objects.]]></description>
+   <tags>example,dynamicscene,declarative,toys,qml,qt quick,dynamic object creation</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-tic-tac-toe-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-toys-tic-tac-toe.html" projectPath="declarative/toys/tic-tac-toe/tic-tac-toe.qmlproject" name="Tic Tac Toe">
+   <description><![CDATA[This example presents a simple implementation of Tic Tac Toe.]]></description>
+   <tags>example,tic-tac-toe,declarative,toys,qml,qt quick</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-clocks-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-toys-clocks.html" projectPath="declarative/toys/clocks/clocks.qmlproject" name="Clocks">
+   <description><![CDATA[This example displays a set of clocks with different times for different cities. Each clock is created by combining <tt>Image</tt> elements with <tt>Rotation</tt> transforms and <tt>SpringAnimation</tt> behaviors.]]></description>
+   <tags>example,clocks,declarative,toys,qml,qt quick,image,rotation,springanimation</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-corkboards-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-toys-corkboards.html" projectPath="declarative/toys/corkboards/corkboards.qmlproject" name="Corkboards">
+   <description><![CDATA[This example presents a flickable set of interactive corkboards. It is created through a combination of elements like <tt>ListModel</tt>, <tt>Repeater</tt> and <tt>TextEdit</tt> together with rotation and scaling transforms, animation and mouse interaction.]]></description>
+   <tags>example,corkboards,declarative,toys,qml,qt quick,listmodel,repeater,textedit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-tvtennis-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-toys-tvtennis.html" projectPath="declarative/toys/tvtennis/tvtennis.qmlproject" name="TV Tennis">
+   <description><![CDATA[This example shows how to use animation components such as <tt>SpringAnimation</tt>, <tt>SequentialAnimation</tt> and <tt>PropertyAction</tt> to create a game of TV tennis.]]></description>
+   <tags>example,tvtennis,declarative,toys,qml,qt quick,springanimation,sequentialanimation,propertyaction</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/calculatorbuilder-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/designer-calculatorbuilder.html" projectPath="designer/calculatorbuilder/calculatorbuilder.pro" name="Calculator Builder">
+   <description><![CDATA[The Calculator Builder example shows how to create a user interface from a <i>Qt Designer</i> form at run-time, using the <tt>QUiLoader</tt> class.]]></description>
+   <tags>example,calculatorbuilder,designer,quiloader</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/calculatorform-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/designer-calculatorform.html" projectPath="designer/calculatorform/calculatorform.pro" name="Calculator Form">
+   <description><![CDATA[The Calculator Form Example shows how to use a form created with <i>Qt Designer</i> in an application by using the user interface information from a <tt>QWidget</tt> subclass. We use <tt>uic's auto-connection</tt> feature to automatically connect signals from widgets on the form to slots in our code.]]></description>
+   <tags>example,calculatorform,designer,qwidget,uic's auto-connection</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/containerextension-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/designer-containerextension.html" projectPath="designer/containerextension/containerextension.pro" name="Container Extension">
+   <description><![CDATA[The Container Extension example shows how to create a custom multi-page plugin for Qt Designer using the <tt>QDesignerContainerExtension</tt> class.]]></description>
+   <tags>example,containerextension,designer,qdesignercontainerextension</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/customwidgetplugin-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/designer-customwidgetplugin.html" projectPath="designer/customwidgetplugin/customwidgetplugin.pro" name="Custom Widget Plugin">
+   <description><![CDATA[The Custom Widget example shows how to create a custom widget plugin for <i>Qt Designer</i>.]]></description>
+   <tags>example,customwidgetplugin,designer</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/designer-taskmenuextension.html" projectPath="designer/taskmenuextension/taskmenuextension.pro" name="Task Menu Extension">
+   <description><![CDATA[The Task Menu Extension example shows how to create a custom widget plugin for <tt><i>Qt Designer</i></tt>, and how to to use the <tt>QDesignerTaskMenuExtension</tt> class to provide custom task menu entries associated with the plugin.]]></description>
+   <tags>example,taskmenuextension,designer,&lt;i>qt designer&lt;/i>,qdesignertaskmenuextension</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/worldtimeclockbuilder-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/designer-worldtimeclockbuilder.html" projectPath="designer/worldtimeclockbuilder/worldtimeclockbuilder.pro" name="World Time Clock Builder">
+   <description><![CDATA[The World Time Clock Builder example shows how forms created with Qt Designer that contain custom widgets can be dynamically generated at run-time.]]></description>
+   <tags>example,worldtimeclockbuilder,designer</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/worldtimeclockplugin-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/designer-worldtimeclockplugin.html" projectPath="designer/worldtimeclockplugin/worldtimeclockplugin.pro" name="World Time Clock Plugin">
+   <description><![CDATA[The World Time Clock Plugin example shows how to create a custom widget plugin for <i>Qt Designer</i> that uses signals and slots.]]></description>
+   <tags>example,worldtimeclockplugin,designer</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/systemtray-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/desktop-systray.html" projectPath="desktop/systray/systray.pro" name="System Tray">
+   <description><![CDATA[The System Tray Icon example shows how to add an icon with a menu and popup messages to a desktop environment's system tray.]]></description>
+   <tags>example,systray,desktop</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/screenshot-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/desktop-screenshot.html" projectPath="desktop/screenshot/screenshot.pro" name="Screenshot">
+   <description><![CDATA[The Screenshot example shows how to take a screenshot of the desktop using <tt>QApplication</tt> and <tt>QDesktopWidget</tt>. It also shows how to use <tt>QTimer</tt> to provide a single-shot timer, and how to reimplement the <tt>QWidget::resizeEvent</tt>() event handler to make sure that an application resizes smoothly and without data loss.]]></description>
+   <tags>example,screenshot,desktop,qapplication,qdesktopwidget,qtimer,qwidget::resizeevent</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/configdialog-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-configdialog.html" projectPath="dialogs/configdialog/configdialog.pro" name="Configuration Dialog">
+   <description><![CDATA[The Config Dialog examples shows how a configuration dialog can be created by using an icon view with a stacked widget.]]></description>
+   <tags>example,configdialog,dialogs</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/extension-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-extension.html" projectPath="dialogs/extension/extension.pro" name="Extension Dialog">
+   <description><![CDATA[The Extension example shows how to add an extension to a <tt>QDialog</tt> using the <tt>QAbstractButton::toggled</tt>() signal and the <tt>QWidget::setVisible</tt>() slot.]]></description>
+   <tags>example,extension,dialogs,qdialog,qabstractbutton::toggled,qwidget::setvisible</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/findfiles-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-findfiles.html" projectPath="dialogs/findfiles/findfiles.pro" name="Find Files Dialog">
+   <description><![CDATA[The Find Files example shows how to use <tt>QProgressDialog</tt> to provide feedback on the progress of a slow operation. The example also shows how to use <tt>QFileDialog</tt> to facilitate browsing, how to use <tt>QTextStream</tt>'s streaming operators to read a file, and how to use <tt>QTableWidget</tt> to provide standard table display facilities for applications. In addition, files can be opened using the <tt>QDesktopServices</tt> class.]]></description>
+   <tags>example,findfiles,dialogs,qprogressdialog,qfiledialog,qtextstream,qtablewidget,qdesktopservices</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/standarddialogs-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-standarddialogs.html" projectPath="dialogs/standarddialogs/standarddialogs.pro" name="Standard Dialogs">
+   <description><![CDATA[The Standard Dialogs example shows the standard dialogs that are provided by Qt.]]></description>
+   <tags>example,standarddialogs,dialogs</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/tabdialog-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-tabdialog.html" projectPath="dialogs/tabdialog/tabdialog.pro" name="Tab Dialog">
+   <description><![CDATA[The Tab Dialog example shows how to construct a tab dialog using the <tt>QTabWidget</tt> class.]]></description>
+   <tags>example,tabdialog,dialogs,qtabwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/trivialwizard-example-introduction.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-trivialwizard.html" projectPath="dialogs/trivialwizard/trivialwizard.pro" name="Trivial Wizard">
+   <description><![CDATA[The Trivial Wizard example illustrates how to create a linear three-page registration wizard using three instances of <tt>QWizardPage</tt> and one instance of <tt>QWizard</tt>.]]></description>
+   <tags>example,trivialwizard,dialogs,qwizardpage,qwizard</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/licensewizard-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-licensewizard.html" projectPath="dialogs/licensewizard/licensewizard.pro" name="License Wizard">
+   <description><![CDATA[The License Wizard example shows how to implement complex wizards in Qt.]]></description>
+   <tags>example,licensewizard,dialogs</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/classwizard.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/dialogs-classwizard.html" projectPath="dialogs/classwizard/classwizard.pro" name="Class Wizard">
+   <description><![CDATA[The License Wizard example shows how to implement linear wizards using <tt>QWizard</tt>.]]></description>
+   <tags>example,classwizard,dialogs,qwizard</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/draggableicons-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/draganddrop-draggableicons.html" projectPath="draganddrop/draggableicons/draggableicons.pro" name="Draggable Icons">
+   <description><![CDATA[The Draggable Icons example shows how to drag and drop image data between widgets in the same application, and between different applications.]]></description>
+   <tags>example,draggableicons,draganddrop</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/draggabletext-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/draganddrop-draggabletext.html" projectPath="draganddrop/draggabletext/draggabletext.pro" name="Draggable Text">
+   <description><![CDATA[The Draggable Text example shows how to drag and drop textual data between widgets in the same application, and between different applications.]]></description>
+   <tags>example,draggabletext,draganddrop</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/dropsite-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/draganddrop-dropsite.html" projectPath="draganddrop/dropsite/dropsite.pro" name="Drop Site">
+   <description><![CDATA[The example shows how to distinguish the various MIME formats available in a drag and drop operation.]]></description>
+   <tags>example,dropsite,draganddrop</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/fridgemagnets-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/draganddrop-fridgemagnets.html" projectPath="draganddrop/fridgemagnets/fridgemagnets.pro" name="Fridge Magnets">
+   <description><![CDATA[The Fridge Magnets example shows how to supply more than one type of MIME-encoded data with a drag and drop operation.]]></description>
+   <tags>example,fridgemagnets,draganddrop</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/draganddroppuzzle-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/draganddrop-puzzle.html" projectPath="draganddrop/puzzle/puzzle.pro" name="Puzzle">
+   <description><![CDATA[The Drag and Drop Puzzle example demonstrates a way of using the drag and drop system with item view widgets.]]></description>
+   <tags>example,puzzle,draganddrop</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/elasticnodes-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/graphicsview-elasticnodes.html" projectPath="graphicsview/elasticnodes/elasticnodes.pro" name="Elastic Nodes">
+   <description><![CDATA[This <tt>GraphicsView</tt> example shows how to implement edges between nodes in a graph, with basic interaction. You can click to drag a node around, and zoom in and out using the mouse wheel or the keyboard. Hitting the space bar will randomize the nodes. The example is also resolution independent; as you zoom in, the graphics remain crisp.]]></description>
+   <tags>example,elasticnodes,graphicsview,graphicsview</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/collidingmice-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/graphicsview-collidingmice.html" projectPath="graphicsview/collidingmice/collidingmice.pro" name="Colliding Mice">
+   <description><![CDATA[The Colliding Mice example shows how to use the Graphics View framework to implement animated items and detect collision between items.]]></description>
+   <tags>example,collidingmice,graphicsview</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/diagramscene.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/graphicsview-diagramscene.html" projectPath="graphicsview/diagramscene/diagramscene.pro" name="Diagram Scene">
+   <description><![CDATA[This example shows use of Qt's graphics framework.]]></description>
+   <tags>example,diagramscene,graphicsview</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/dragdroprobot-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/graphicsview-dragdroprobot.html" projectPath="graphicsview/dragdroprobot/dragdroprobot.pro" name="Drag and Drop Robot">
+   <description><![CDATA[This <tt>GraphicsView</tt> example shows how to implement Drag and Drop in a <tt>QGraphicsItem</tt> subclass, as well as how to animate items using Qt's <tt>Animation Framework</tt>.]]></description>
+   <tags>example,dragdroprobot,graphicsview,graphicsview,qgraphicsitem,animation framework</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/portedcanvas-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/graphicsview-portedcanvas.html" projectPath="graphicsview/portedcanvas/portedcanvas.pro" name="Ported Canvas">
+   <description><![CDATA[This <tt>GraphicsView</tt> example is a port of the old <tt>QCanvas</tt> example from Qt 3.]]></description>
+   <tags>example,portedcanvas,graphicsview,graphicsview,qcanvas</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/portedasteroids-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/graphicsview-portedasteroids.html" projectPath="graphicsview/portedasteroids/portedasteroids.pro" name="Ported Asteroids">
+   <description><![CDATA[This <tt>GraphicsView</tt> example is a port of the Asteroids game, which was based on <tt>QCanvas</tt>.]]></description>
+   <tags>example,portedasteroids,graphicsview,graphicsview,qcanvas</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/padnavigator-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/graphicsview-padnavigator.html" projectPath="graphicsview/padnavigator/padnavigator.pro" name="Pad Navigator Example">
+   <description><![CDATA[The Pad Navigator Example shows how you can use Graphics View together with embedded widgets and Qt's <tt>State Machine Framework</tt> to create a simple but useful, dynamic, animated user interface.]]></description>
+   <tags>example,padnavigator,graphicsview,state machine framework</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/sharedmemory-example_1.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/ipc-sharedmemory.html" projectPath="ipc/sharedmemory/sharedmemory.pro" name="Shared Memory">
+   <description><![CDATA[The Shared Memory example shows how to use the <tt>QSharedMemory</tt> class to implement inter-process communication using shared memory. To build the example, run make. To run the example, start two instances of the executable. The main() function creates an <tt>application</tt> and an instance of our example's Dialog class. The dialog is displayed and then control is passed to the application in the standard way.]]></description>
+   <tags>example,sharedmemory,ipc,qsharedmemory,application</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/localfortuneclient-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/ipc-localfortuneclient.html" projectPath="ipc/localfortuneclient/localfortuneclient.pro" name="Local Fortune Client">
+   <description><![CDATA[The Local Fortune Client example shows how to create a client for a simple local service using <tt>QLocalSocket</tt>. It is intended to be run alongside the <tt>Local Fortune Server</tt> example.]]></description>
+   <tags>example,localfortuneclient,ipc,qlocalsocket,local fortune server</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/localfortuneserver-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/ipc-localfortuneserver.html" projectPath="ipc/localfortuneserver/localfortuneserver.pro" name="Local Fortune Server">
+   <description><![CDATA[The Local Fortune Server example shows how to create a server for a simple local service. It is intended to be run alongside the <tt>Local Fortune Client</tt> example]]></description>
+   <tags>example,localfortuneserver,ipc,local fortune client</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-addressbook.html" projectPath="itemviews/addressbook/addressbook.pro" name="Address Book">
+   <description><![CDATA[The address book example shows how to use proxy models to display different views onto data from a single model.]]></description>
+   <tags>example,addressbook,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/basicsortfiltermodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-basicsortfiltermodel.html" projectPath="itemviews/basicsortfiltermodel/basicsortfiltermodel.pro" name="Basic Sort/Filter Model">
+   <description><![CDATA[The Basic Sort/Filter Model example illustrates how to use <tt>QSortFilterProxyModel</tt> to perform basic sorting and filtering.]]></description>
+   <tags>example,basicsortfiltermodel,itemviews,qsortfilterproxymodel</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/chart-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-chart.html" projectPath="itemviews/chart/chart.pro" name="Chart">
+   <description><![CDATA[The Chart example shows how to create a custom view for the model/view framework.]]></description>
+   <tags>example,chart,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/customsortfiltermodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-customsortfiltermodel.html" projectPath="itemviews/customsortfiltermodel/customsortfiltermodel.pro" name="Custom Sort/Filter Model">
+   <description><![CDATA[The Custom Sort/Filter Model example illustrates how to subclass <tt>QSortFilterProxyModel</tt> to perform advanced sorting and filtering.]]></description>
+   <tags>example,customsortfiltermodel,itemviews,qsortfilterproxymodel</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/coloreditorfactoryimage.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-coloreditorfactory.html" projectPath="itemviews/coloreditorfactory/coloreditorfactory.pro" name="Color Editor Factory">
+   <description><![CDATA[This example shows how to create an editor that can be used by a <tt>QItemDelegate</tt>.]]></description>
+   <tags>example,coloreditorfactory,itemviews,qitemdelegate</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/combowidgetmapper-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-combowidgetmapper.html" projectPath="itemviews/combowidgetmapper/combowidgetmapper.pro" name="Combo Widget Mapper">
+   <description><![CDATA[The Delegate Widget Mapper example shows how to use a custom delegate to map information from a model to specific widgets on a form.]]></description>
+   <tags>example,combowidgetmapper,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/dirview-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-dirview.html" projectPath="itemviews/dirview/dirview.pro" name="Directory View">
+   <description><![CDATA[The Dir View example shows a tree view onto the local filing system. It uses the <tt>QDirModel(obsolete)</tt> class to provide supply file and directory information.]]></description>
+   <tags>example,dirview,itemviews,qdirmodel(obsolete)</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/fetchmore-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-fetchmore.html" projectPath="itemviews/fetchmore/fetchmore.pro" name="Fetch More">
+   <description><![CDATA[The Fetch More example shows how two add items to an item view model on demand.]]></description>
+   <tags>example,fetchmore,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/frozencolumn-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-frozencolumn.html" projectPath="itemviews/frozencolumn/frozencolumn.pro" name="Frozen Column">
+   <description><![CDATA[This example demonstrates how to freeze a column within a <tt>QTableView</tt>.]]></description>
+   <tags>example,frozencolumn,itemviews,qtableview</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/pixelator-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-pixelator.html" projectPath="itemviews/pixelator/pixelator.pro" name="Pixelator">
+   <description><![CDATA[The Pixelator example shows how delegates can be used to customize the way that items are rendered in standard item views.]]></description>
+   <tags>example,pixelator,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/itemviewspuzzle-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-puzzle.html" projectPath="itemviews/puzzle/puzzle.pro" name="Puzzle ">
+   <description><![CDATA[The Puzzle example shows how to enable drag and drop with a custom model to allow items to be transferred between a view and another widget.]]></description>
+   <tags>example,puzzle,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/simpledommodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-simpledommodel.html" projectPath="itemviews/simpledommodel/simpledommodel.pro" name="Simple DOM Model">
+   <description><![CDATA[The Simple DOM Model example shows how an existing class can be adapted for use with the model/view framework.]]></description>
+   <tags>example,simpledommodel,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/simpletreemodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-simpletreemodel.html" projectPath="itemviews/simpletreemodel/simpletreemodel.pro" name="Simple Tree Model">
+   <description><![CDATA[The Simple Tree Model example shows how to create a basic, read-only hierarchical model to use with Qt's standard view classes. For a description of simple non-hierarchical list and table models, see the <tt>Model/View Programming</tt> overview.]]></description>
+   <tags>example,simpletreemodel,itemviews,model/view programming</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/simplewidgetmapper-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-simplewidgetmapper.html" projectPath="itemviews/simplewidgetmapper/simplewidgetmapper.pro" name="Simple Widget Mapper">
+   <description><![CDATA[The Simple Widget Mapper example shows how to use a widget mapper to display data from a model in a collection of widgets.]]></description>
+   <tags>example,simplewidgetmapper,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/spinboxdelegate-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-spinboxdelegate.html" projectPath="itemviews/spinboxdelegate/spinboxdelegate.pro" name="Spin Box Delegate">
+   <description><![CDATA[The Spin Box Delegate example shows how to create an editor for a custom delegate in the model/view framework by reusing a standard Qt editor widget.]]></description>
+   <tags>example,spinboxdelegate,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/stardelegate.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/itemviews-stardelegate.html" projectPath="itemviews/stardelegate/stardelegate.pro" name="Star Delegate">
+   <description><![CDATA[The Star Delegate example shows how to create a delegate that can paint itself and that supports editing.]]></description>
+   <tags>example,stardelegate,itemviews</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/basiclayouts-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/layouts-basiclayouts.html" projectPath="layouts/basiclayouts/basiclayouts.pro" name="Basic Layouts">
+   <description><![CDATA[The Basic Layouts example shows how to use the standard layout managers that are available in Qt: <tt>QBoxLayout</tt>, <tt>QGridLayout</tt> and <tt>QFormLayout</tt>.]]></description>
+   <tags>example,basiclayouts,layouts,qboxlayout,qgridlayout,qformlayout</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/borderlayout-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/layouts-borderlayout.html" projectPath="layouts/borderlayout/borderlayout.pro" name="Border Layout">
+   <description><![CDATA[The Border Layout example shows how to create a custom layout that arranges child widgets according to a simple set of rules.]]></description>
+   <tags>example,borderlayout,layouts</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/layouts-dynamiclayouts.html" projectPath="layouts/dynamiclayouts/dynamiclayouts.pro" name="Dynamic Layouts">
+   <description><![CDATA[The Dynamic Layouts example shows how to move widgets around in existing layouts.]]></description>
+   <tags>example,dynamiclayouts,layouts</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/flowlayout-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/layouts-flowlayout.html" projectPath="layouts/flowlayout/flowlayout.pro" name="Flow Layout">
+   <description><![CDATA[The Flow Layout example demonstrates a custom layout that arranges child widgets from left to right and top to bottom in a top-level widget.]]></description>
+   <tags>example,flowlayout,layouts</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/linguist-arrowpad_en.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/linguist-arrowpad.html" projectPath="linguist/arrowpad/arrowpad.pro" name="Arrow Pad">
+   <description><![CDATA[This example is a slightly more involved and introduces a key <i>Qt Linguist</i> concept: "contexts". It also shows how to use two or more languages.]]></description>
+   <tags>example,arrowpad,linguist</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/linguist-hellotr_en.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/linguist-hellotr.html" projectPath="linguist/hellotr/hellotr.pro" name="Hello World">
+   <description><![CDATA[This example is a small Hello World program with a Latin translation. The screenshot below shows the English version.]]></description>
+   <tags>example,hellotr,linguist</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/linguist-trollprint_10_en.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/linguist-trollprint.html" projectPath="linguist/trollprint/trollprint.pro" name="Troll Print">
+   <description><![CDATA[Troll Print is an example application that lets the user choose printer settings. It comes in two versions: English and Portuguese.]]></description>
+   <tags>example,trollprint,linguist</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/application.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/mainwindows-application.html" projectPath="mainwindows/application/application.pro" name="Application">
+   <description><![CDATA[The Application example shows how to implement a standard GUI application with menus, toolbars, and a status bar. The example itself is a simple text editor program built around <tt>QPlainTextEdit</tt>.]]></description>
+   <tags>example,application,mainwindows,qplaintextedit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/dockwidgets-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/mainwindows-dockwidgets.html" projectPath="mainwindows/dockwidgets/dockwidgets.pro" name="Dock Widgets">
+   <description><![CDATA[The Dock Widgets example shows how to add dock windows to an application. It also shows how to use Qt's rich text engine.]]></description>
+   <tags>example,dockwidgets,mainwindows</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/mdi-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/mainwindows-mdi.html" projectPath="mainwindows/mdi/mdi.pro" name="MDI">
+   <description><![CDATA[The MDI example shows how to implement a Multiple Document Interface using Qt's <tt>QMdiArea</tt> class.]]></description>
+   <tags>example,mdi,mainwindows,qmdiarea</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/sdi-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/mainwindows-sdi.html" projectPath="mainwindows/sdi/sdi.pro" name="SDI">
+   <description><![CDATA[The SDI example shows how to create a Single Document Interface. It uses a number of top-level windows to display the contents of different text files.]]></description>
+   <tags>example,sdi,mainwindows</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/menus-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/mainwindows-menus.html" projectPath="mainwindows/menus/menus.pro" name="Menus">
+   <description><![CDATA[The Menus example demonstrates how menus can be used in a main window application.]]></description>
+   <tags>example,menus,mainwindows</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/recentfiles-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/mainwindows-recentfiles.html" projectPath="mainwindows/recentfiles/recentfiles.pro" name="Recent Files">
+   <description><![CDATA[The Recent Files example shows how a standard File menu can be extended to show the most recent files loaded by a main window application.]]></description>
+   <tags>example,recentfiles,mainwindows</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-dialcontrol-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-dialcontrol.html" projectPath="declarative/ui-components/dialcontrol/dialcontrol.qmlproject" name="Dial">
+   <description><![CDATA[This example shows how to create a dial-type control. It combines <tt>Image</tt> elements with <tt>Rotation</tt> transforms and <tt>SpringAnimation</tt> behaviors to produce an interactive speedometer-type dial.]]></description>
+   <tags>example,dialcontrol,declarative,ui-components,qml,qt quick,image,rotation,springanimation</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-flipable-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-flipable.html" projectPath="declarative/ui-components/flipable/flipable.qmlproject" name="Flipable">
+   <description><![CDATA[This example shows how to use the <tt>Flipable</tt> element.]]></description>
+   <tags>example,flipable,declarative,ui-components,qml,qt quick,flipable</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-progressbar-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-progressbar.html" projectPath="declarative/ui-components/progressbar/progressbar.qmlproject" name="Progress bar">
+   <description><![CDATA[This example shows how to create a progress bar.]]></description>
+   <tags>example,progressbar,declarative,ui-components,qml,qt quick</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-scrollbar-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-scrollbar.html" projectPath="declarative/ui-components/scrollbar/scrollbar.qmlproject" name="Scroll bar">
+   <description><![CDATA[This example shows how to create scroll bars for a <tt>Flickable</tt> element using the <tt>Flickable::visibleArea</tt> properties.]]></description>
+   <tags>example,scrollbar,declarative,ui-components,qml,qt quick,flickable,flickable::visiblearea</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-searchbox-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-searchbox.html" projectPath="declarative/ui-components/searchbox/searchbox.qmlproject" name="Search box">
+   <description><![CDATA[This example shows how to combine <tt>TextInput</tt>, <tt>FocusScope</tt> and <tt>BorderImage</tt> elements to display multiple text input fields.]]></description>
+   <tags>example,searchbox,declarative,ui-components,qml,qt quick,textinput,focusscope,borderimage</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-slideswitch-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-slideswitch.html" projectPath="declarative/ui-components/slideswitch/slideswitch.qmlproject" name="Slide switch">
+   <description><![CDATA[This example shows how to create a slide switch control.]]></description>
+   <tags>example,slideswitch,declarative,ui-components,qml,qt quick</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-spinner-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-spinner.html" projectPath="declarative/ui-components/spinner/spinner.qmlproject" name="Spinner">
+   <description><![CDATA[This example shows how to create a spinner-type component using the <tt>PathView</tt> element.]]></description>
+   <tags>example,spinner,declarative,ui-components,qml,qt quick,pathview</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qml-tabwidget-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/declarative-ui-components-tabwidget.html" projectPath="declarative/ui-components/tabwidget/tabwidget.qmlproject" name="Tab widget">
+   <description><![CDATA[This example shows how to create a tab widget. It also demonstrates how <tt>property aliases</tt> and <tt>default properties</tt> can be used to collect and assemble the child items declared within an <tt>Item</tt>.]]></description>
+   <tags>example,tabwidget,declarative,ui-components,qml,qt quick,property aliases,default properties,item</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/blockingfortuneclient-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-blockingfortuneclient.html" projectPath="network/blockingfortuneclient/blockingfortuneclient.pro" name="Blocking Fortune Client">
+   <description><![CDATA[The Blocking Fortune Client example shows how to create a client for a network service using <tt>QTcpSocket</tt>'s synchronous API in a non-GUI thread.]]></description>
+   <tags>example,blockingfortuneclient,network,qtcpsocket</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/broadcastreceiver-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-broadcastreceiver.html" projectPath="network/broadcastreceiver/broadcastreceiver.pro" name="Broadcast Receiver">
+   <description><![CDATA[The Broadcast Receiever example shows how to receive information that is broadcasted over a local network.]]></description>
+   <tags>example,broadcastreceiver,network</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/broadcastsender-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-broadcastsender.html" projectPath="network/broadcastsender/broadcastsender.pro" name="Broadcast Sender">
+   <description><![CDATA[The Broadcast Sender example shows how to broadcast information to multiple clients on a local network.]]></description>
+   <tags>example,broadcastsender,network</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/network-chat-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-network-chat.html" projectPath="network/network-chat/network-chat.pro" name="Network Chat Client">
+   <description><![CDATA[The Network Chat example demonstrates a stateful peer-to-peer Chat client that uses broadcasting with <tt>QUdpSocket</tt> and <tt>QNetworkInterface</tt> to discover its peers.]]></description>
+   <tags>example,network-chat,network,qudpsocket,qnetworkinterface</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/fortuneclient-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-fortuneclient.html" projectPath="network/fortuneclient/fortuneclient.pro" name="Fortune Client">
+   <description><![CDATA[The Fortune Client example shows how to create a client for a simple network service using <tt>QTcpSocket</tt>. It is intended to be run alongside the <tt>Fortune Server</tt> example or the <tt>Threaded Fortune Server</tt> example.]]></description>
+   <tags>example,fortuneclient,network,qtcpsocket,fortune server,threaded fortune server</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/fortuneserver-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-fortuneserver.html" projectPath="network/fortuneserver/fortuneserver.pro" name="Fortune Server">
+   <description><![CDATA[The Fortune Server example shows how to create a server for a simple network service. It is intended to be run alongside the <tt>Fortune Client</tt> example or the <tt>Blocking Fortune Client</tt> example.]]></description>
+   <tags>example,fortuneserver,network,fortune client,blocking fortune client</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-qftp.html" projectPath="network/qftp/qftp.pro" name="FTP Client">
+   <description><![CDATA[The FTP example demonstrates a simple FTP client that can be used to list the available files on an FTP server and download them.]]></description>
+   <tags>example,qftp,network</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/http-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-http.html" projectPath="network/http/http.pro" name="HTTP Client">
+   <description><![CDATA[The HTTP example demonstrates a simple HTTP client that shows how to fetch files specified by URLs from remote hosts.]]></description>
+   <tags>example,http,network</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/loopback-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-loopback.html" projectPath="network/loopback/loopback.pro" name="Loopback">
+   <description><![CDATA[The Loopback example shows how to communicate between simple clients and servers on a local host.]]></description>
+   <tags>example,loopback,network</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/threadedfortuneserver-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-threadedfortuneserver.html" projectPath="network/threadedfortuneserver/threadedfortuneserver.pro" name="Threaded Fort. Server">
+   <description><![CDATA[The Threaded Fortune Server example shows how to create a server for a simple network service that uses threads to handle requests from different clients. It is intended to be run alongside the Fortune Client example.]]></description>
+   <tags>example,threadedfortuneserver,network</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/torrent-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-torrent.html" projectPath="network/torrent/torrent.pro" name="Torrent Client">
+   <description><![CDATA[The Torrent example is a functional BitTorrent client that illustrates how to write a complex TCP/IP application using Qt.]]></description>
+   <tags>example,torrent,network</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/securesocketclient.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-securesocketclient.html" projectPath="network/securesocketclient/securesocketclient.pro" name="Secure Socket Client">
+   <description><![CDATA[The Secure Socket Client example shows how to use <tt>QSslSocket</tt> to communicate over an encrypted (SSL) connection. It also demonstrates how to deal with authenticity problems, and how to display security and certificate information.]]></description>
+   <tags>example,securesocketclient,network,qsslsocket</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/googlesuggest-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/network-googlesuggest.html" projectPath="network/googlesuggest/googlesuggest.pro" name="Google Suggest">
+   <description><![CDATA[The Google Suggest example demonstrates how to use the <tt>QNetworkAccessManager</tt> class to obtain a list of suggestions from the Google search engine as the user types into a <tt>QLineEdit</tt>.]]></description>
+   <tags>example,googlesuggest,network,qnetworkaccessmanager,qlineedit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/2dpainting-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-2dpainting.html" projectPath="opengl/2dpainting/2dpainting.pro" name="2D Painting">
+   <description><![CDATA[The 2D Painting example shows how <tt>QPainter</tt> and <tt>QGLWidget</tt> can be used together to display accelerated 2D graphics on supported hardware.]]></description>
+   <tags>example,2dpainting,opengl,qpainter,qglwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/framebufferobject-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-framebufferobject.html" projectPath="opengl/framebufferobject/framebufferobject.pro" name="Framebuffer Object">
+   <description><![CDATA[The Framebuffer Object example demonstrates how to use the <tt>QGLFramebufferObject</tt> class to render into an off-screen buffer and use the contents as a texture in a <tt>QGLWidget</tt>.]]></description>
+   <tags>example,framebufferobject,opengl,qglframebufferobject,qglwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/framebufferobject2-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-framebufferobject2.html" projectPath="opengl/framebufferobject2/framebufferobject2.pro" name="Framebuffer Object 2">
+   <description><![CDATA[The Framebuffer Object 2 example demonstrates how to use the <tt>QGLFramebufferObject</tt> class to render into an off-screen buffer and use the contents as a texture in a <tt>QGLWidget</tt>.]]></description>
+   <tags>example,framebufferobject2,opengl,qglframebufferobject,qglwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/grabber-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-grabber.html" projectPath="opengl/grabber/grabber.pro" name="Grabber">
+   <description><![CDATA[The Grabber examples shows how to retrieve the contents of an OpenGL framebuffer.]]></description>
+   <tags>example,grabber,opengl</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/hellogl-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-hellogl.html" projectPath="opengl/hellogl/hellogl.pro" name="Hello GL">
+   <description><![CDATA[The Hello GL example demonstrates the basic use of the OpenGL-related classes provided with Qt.]]></description>
+   <tags>example,hellogl,opengl</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/overpainting-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-overpainting.html" projectPath="opengl/overpainting/overpainting.pro" name="Overpainting">
+   <description><![CDATA[The Overpainting example shows how <tt>QPainter</tt> can be used to overpaint a scene rendered using OpenGL in a <tt>QGLWidget</tt>.]]></description>
+   <tags>example,overpainting,opengl,qpainter,qglwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/pbuffers-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-pbuffers.html" projectPath="opengl/pbuffers/pbuffers.pro" name="Pixel Buffers">
+   <description><![CDATA[The Pixel Buffers example demonstrates how to use the <tt>QGLPixelBuffer</tt> class to render into an off-screen buffer and use the contents as a dynamic texture in a <tt>QGLWidget</tt>.]]></description>
+   <tags>example,pbuffers,opengl,qglpixelbuffer,qglwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/pbuffers2-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-pbuffers2.html" projectPath="opengl/pbuffers2/pbuffers2.pro" name="Pixel Buffers 2">
+   <description><![CDATA[The Pixel Buffers 2 example demonstrates how to use the <tt>QGLPixelBuffer</tt> class to render into an off-screen buffer and use the contents as a dynamic texture in a <tt>QGLWidget</tt>.]]></description>
+   <tags>example,pbuffers2,opengl,qglpixelbuffer,qglwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/samplebuffers-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-samplebuffers.html" projectPath="opengl/samplebuffers/samplebuffers.pro" name="Sample Buffers">
+   <description><![CDATA[The Sample Buffers example demonstrates how to use and enable sample buffers in a <tt>QGLWidget</tt>.]]></description>
+   <tags>example,samplebuffers,opengl,qglwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/textures-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/opengl-textures.html" projectPath="opengl/textures/textures.pro" name="Textures">
+   <description><![CDATA[The Textures example demonstrates the use of Qt's image classes as textures in applications that use both OpenGL and Qt to display graphics.]]></description>
+   <tags>example,textures,opengl</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/basicdrawing-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-basicdrawing.html" projectPath="painting/basicdrawing/basicdrawing.pro" name="Basic Drawing">
+   <description><![CDATA[The Basic Drawing example shows how to display basic graphics primitives in a variety of styles using the <tt>QPainter</tt> class.]]></description>
+   <tags>example,basicdrawing,painting,qpainter</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/concentriccircles-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-concentriccircles.html" projectPath="painting/concentriccircles/concentriccircles.pro" name="Concentric Circles">
+   <description><![CDATA[The Concentric Circles example shows the improved rendering quality that can be obtained using floating point precision and anti-aliasing when drawing custom widgets. The example also shows how to do simple animations.]]></description>
+   <tags>example,concentriccircles,painting</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/fontsampler-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-fontsampler.html" projectPath="painting/fontsampler/fontsampler.pro" name="Font Sampler">
+   <description><![CDATA[The Font Sampler example shows how to preview and print multi-page documents.]]></description>
+   <tags>example,fontsampler,painting</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/imagecomposition-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-imagecomposition.html" projectPath="painting/imagecomposition/imagecomposition.pro" name="Image Composition">
+   <description><![CDATA[The Image Composition example lets the user combine images together using any composition mode supported by <tt>QPainter</tt>, described in detail in <tt>Composition Modes</tt>.]]></description>
+   <tags>example,imagecomposition,painting,qpainter,composition modes</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/painterpaths-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-painterpaths.html" projectPath="painting/painterpaths/painterpaths.pro" name="Painter Paths">
+   <description><![CDATA[The Painter Paths example shows how painter paths can be used to build complex shapes for rendering.]]></description>
+   <tags>example,painterpaths,painting</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/svggenerator-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-svggenerator.html" projectPath="painting/svggenerator/svggenerator.pro" name="SVG Generator">
+   <description><![CDATA[The SVG Generator example shows how to add SVG file export to applications.]]></description>
+   <tags>example,svggenerator,painting</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/svgviewer-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-svgviewer.html" projectPath="painting/svgviewer/svgviewer.pro" name="SVG Viewer">
+   <description><![CDATA[The SVG Viewer example shows how to add SVG viewing support to applications.]]></description>
+   <tags>example,svgviewer,painting</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/transformations-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/painting-transformations.html" projectPath="painting/transformations/transformations.pro" name="Transformations">
+   <description><![CDATA[The Transformations example shows how transformations influence the way that <tt>QPainter</tt> renders graphics primitives. In particular it shows how the order of transformations affect the result.]]></description>
+   <tags>example,transformations,painting,qpainter</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/phonon-qmusicplayer.html" projectPath="phonon/qmusicplayer/qmusicplayer.pro" name="Music Player">
+   <description><![CDATA[The Music Player Example shows how to use Phonon - the multimedia framework that comes with Qt - to create a simple music player. The player can play music files, and provides simple playback control, such as pausing, stopping, and resuming the music.]]></description>
+   <tags>example,qmusicplayer,phonon</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/audiodevices-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/multimedia-audiodevices.html" projectPath="multimedia/audiodevices/audiodevices.pro" name="Audio Devices">
+   <description><![CDATA[The Audio Devices example demonstrates the basic use of <tt>QAudioDeviceInfo</tt> class provided with Qt.]]></description>
+   <tags>example,audiodevices,multimedia,qaudiodeviceinfo</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/audiooutput-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/multimedia-audiooutput.html" projectPath="multimedia/audiooutput/audiooutput.pro" name="Audio Output">
+   <description><![CDATA[The Audio Output example demonstrates the basic use of the <tt>QAudioOutput</tt> class provided with Qt.]]></description>
+   <tags>example,audiooutput,multimedia,qaudiooutput</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/audioinput-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/multimedia-audioinput.html" projectPath="multimedia/audioinput/audioinput.pro" name="Audio Input">
+   <description><![CDATA[The Audio Input example demonstrates the basic use of <tt>QAudioInput</tt> class provided with Qt.]]></description>
+   <tags>example,audioinput,multimedia,qaudioinput</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/calendar-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/richtext-calendar.html" projectPath="richtext/calendar/calendar.pro" name="Calendar">
+   <description><![CDATA[The Calendar example shows how to create rich text content and display it using a rich text editor.]]></description>
+   <tags>example,calendar,richtext</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/orderform-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/richtext-orderform.html" projectPath="richtext/orderform/orderform.pro" name="Order Form">
+   <description><![CDATA[The Order Form example shows how to generate rich text documents by combining a simple template with data input by the user in a dialog. Data is extracted from a <tt>DetailsDialog</tt> object and displayed on a <tt>QTextEdit</tt> with a <tt>QTextCursor</tt>, using various formats. Each form generated is added to a <tt>QTabWidget</tt> for easy access.]]></description>
+   <tags>example,orderform,richtext,detailsdialog,qtextedit,qtextcursor,qtabwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/syntaxhighlighter-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/richtext-syntaxhighlighter.html" projectPath="richtext/syntaxhighlighter/syntaxhighlighter.pro" name="Syntax Highlighter">
+   <description><![CDATA[The Syntax Highlighter example shows how to perform simple syntax highlighting by subclassing the <tt>QSyntaxHighlighter</tt> class.]]></description>
+   <tags>example,syntaxhighlighter,richtext,qsyntaxhighlighter</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/textobject-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/richtext-textobject.html" projectPath="richtext/textobject/textobject.pro" name="Text Object">
+   <description><![CDATA[The Text Object example shows how to insert an SVG file into a <tt>QTextDocument</tt>.]]></description>
+   <tags>example,textobject,richtext,qtextdocument</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/calculator-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/script-calculator.html" projectPath="script/calculator/calculator.pro" name="Calculator">
+   <description><![CDATA[In this simple <tt>QtScript</tt> example, we show how to implement the functionality of a calculator widget.]]></description>
+   <tags>example,calculator,script,qtscript</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/context2d-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/script-context2d.html" projectPath="script/context2d/context2d.pro" name="Context2D">
+   <description><![CDATA[This Qt Script example is an implementation of the Context2D API.]]></description>
+   <tags>example,context2d,script</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/defaultprototypes-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/script-defaultprototypes.html" projectPath="script/defaultprototypes/defaultprototypes.pro" name="Default Prototypes">
+   <description><![CDATA[This Qt Script example shows how to use default prototypes to make a non-<tt>QObject</tt>-based type scriptable.]]></description>
+   <tags>example,defaultprototypes,script,qobject</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/t1.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/script-helloscript.html" projectPath="script/helloscript/helloscript.pro" name="Hello Script">
+   <description><![CDATA[The Hello Script example shows the basic use of Qt Script: How to embed a script engine into the application, how to evaluate a script, and how to process the result of the evaluation. The example also shows how to apply internationalization to scripts.]]></description>
+   <tags>example,helloscript,script</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/tetrix-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/script-qstetrix.html" projectPath="script/qstetrix/qstetrix.pro" name="QSTetrix">
+   <description><![CDATA[The QSTetrix example is a Qt Script version of the classic Tetrix game.]]></description>
+   <tags>example,qstetrix,script</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/cachedtable-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/sql-cachedtable.html" projectPath="sql/cachedtable/cachedtable.pro" name="Cached Table">
+   <description><![CDATA[The Cached Table example shows how a table view can be used to access a database, caching any changes to the data until the user explicitly submits them using a push button.]]></description>
+   <tags>example,cachedtable,sql</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/drilldown-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/sql-drilldown.html" projectPath="sql/drilldown/drilldown.pro" name="Drill Down">
+   <description><![CDATA[The Drill Down example shows how to read data from a database as well as submit changes, using the <tt>QSqlRelationalTableModel</tt> and <tt>QDataWidgetMapper</tt> classes.]]></description>
+   <tags>example,drilldown,sql,qsqlrelationaltablemodel,qdatawidgetmapper</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/querymodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/sql-querymodel.html" projectPath="sql/querymodel/querymodel.pro" name="Query Model">
+   <description><![CDATA[The Query Model example shows how to make customized versions of data obtained from a SQL query, using a model that encapsulates the query and table views to display the results.]]></description>
+   <tags>example,querymodel,sql</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/relationaltablemodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/sql-relationaltablemodel.html" projectPath="sql/relationaltablemodel/relationaltablemodel.pro" name="Relational Table Model">
+   <description><![CDATA[The Relational Table Model example shows how to use table views with a relational model to visualize the relations between items in a database.]]></description>
+   <tags>example,relationaltablemodel,sql</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/tablemodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/sql-tablemodel.html" projectPath="sql/tablemodel/tablemodel.pro" name="Table Model">
+   <description><![CDATA[The Table Model example shows how to use a specialized SQL table model with table views to edit information in a database.]]></description>
+   <tags>example,tablemodel,sql</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/masterdetail-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/sql-masterdetail.html" projectPath="sql/masterdetail/masterdetail.pro" name="Music Archive">
+   <description><![CDATA[The Master Detail Example shows how to present data from different data sources in the same application. The album titles, and the corresponding artists and release dates, are kept in a database, while each album's tracks are stored in an XML file.]]></description>
+   <tags>example,masterdetail,sql</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/sql-sqlwidgetmapper.html" projectPath="sql/sqlwidgetmapper/sqlwidgetmapper.pro" name="SQL Widget Mapper">
+   <description><![CDATA[The SQL Widget Mapper example shows how to use a map information from a database to widgets on a form.]]></description>
+   <tags>example,sqlwidgetmapper,sql</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/statemachine-eventtransitions.html" projectPath="statemachine/eventtransitions/eventtransitions.pro" name="Event Transitions">
+   <description><![CDATA[The Event Transitions example shows how to use event transitions, a feature of <tt>The State Machine Framework</tt>.]]></description>
+   <tags>example,eventtransitions,statemachine,the state machine framework</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/rogue-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/statemachine-rogue.html" projectPath="statemachine/rogue/rogue.pro" name="Rogue">
+   <description><![CDATA[The Rogue example shows how to use the Qt state machine for event handling.]]></description>
+   <tags>example,rogue,statemachine</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/trafficlight-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/statemachine-trafficlight.html" projectPath="statemachine/trafficlight/trafficlight.pro" name="Traffic Light">
+   <description><![CDATA[The Traffic Light example shows how to use <tt>The State Machine Framework</tt> to implement the control flow of a traffic light.]]></description>
+   <tags>example,trafficlight,statemachine,the state machine framework</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/statemachine-twowaybutton.html" projectPath="statemachine/twowaybutton/twowaybutton.pro" name="Two-way Button">
+   <description><![CDATA[The Two-way button example shows how to use <tt>The State Machine Framework</tt> to implement a simple state machine that toggles the current state when a button is clicked.]]></description>
+   <tags>example,twowaybutton,statemachine,the state machine framework</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/mandelbrot-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/threads-mandelbrot.html" projectPath="threads/mandelbrot/mandelbrot.pro" name="Mandelbrot">
+   <description><![CDATA[The Mandelbrot example shows how to use a worker thread to perform heavy computations without blocking the main thread's event loop.]]></description>
+   <tags>example,mandelbrot,threads</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/codecs-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-codecs.html" projectPath="tools/codecs/codecs.pro" name="Codecs">
+   <description><![CDATA[The Codecs example demonstrates the principles behind importing and exporting text using codecs to ensure that characters are encoded properly, avoiding loss of data and retaining the correct symbols used in various scripts.]]></description>
+   <tags>example,codecs,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/completer-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-completer.html" projectPath="tools/completer/completer.pro" name="Completer">
+   <description><![CDATA[The Completer example shows how to provide string-completion facilities for an input widget based on data provided by a model.]]></description>
+   <tags>example,completer,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/customcompleter-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-customcompleter.html" projectPath="tools/customcompleter/customcompleter.pro" name="Custom Completer">
+   <description><![CDATA[The Custom Completer example shows how to provide string-completion facilities for an input widget based on data provided by a model. The completer pops up suggestions for possible words based on the first three characters input by the user and the user's choice of word is inserted into the <tt>TextEdit</tt> using <tt>QTextCursor</tt>.]]></description>
+   <tags>example,customcompleter,tools,textedit,qtextcursor</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/i18n-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-i18n.html" projectPath="tools/i18n/i18n.pro" name="Internationalization">
+   <description><![CDATA[The Internationalization (I18N) example demonstrates Qt's support for translated text. Developers can write the initial application text in one language, and translations can be provided later without any modifications to the code.]]></description>
+   <tags>example,i18n,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/inputpanel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-inputpanel.html" projectPath="tools/inputpanel/inputpanel.pro" name="Input Panel">
+   <description><![CDATA[The Input Panel example shows how to create an input panel that can be used to input text into widgets using only the pointer and no keyboard.]]></description>
+   <tags>example,inputpanel,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/plugandpaint.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-plugandpaint.html" projectPath="tools/plugandpaint/plugandpaint.pro" name="Plug and Paint">
+   <description><![CDATA[The Plug & Paint example demonstrates how to write Qt applications that can be extended through plugins.]]></description>
+   <tags>example,plugandpaint,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/regexp-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-regexp.html" projectPath="tools/regexp/regexp.pro" name="Regular Expressions">
+   <description><![CDATA[The Regular Expressions (RegExp) example shows how regular expressions in Qt are applied to text by providing an environment in which new regular expressions can be created and tested on custom text strings.]]></description>
+   <tags>example,regexp,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/settingseditor-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-settingseditor.html" projectPath="tools/settingseditor/settingseditor.pro" name="Settings Editor">
+   <description><![CDATA[The Settings Editor example shows how Qt's standard settings support is used in an application by providing an editor that enables the user to view the settings for installed applications, and modify those that can be edited.]]></description>
+   <tags>example,settingseditor,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/treemodelcompleter-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-treemodelcompleter.html" projectPath="tools/treemodelcompleter/treemodelcompleter.pro" name="Tree Model Completer">
+   <description><![CDATA[The Tree Model Completer example shows how to provide completion facilities for a hierarchical model, using a period as the separator to access Child, GrandChild and GrandGrandChild level objects.]]></description>
+   <tags>example,treemodelcompleter,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/undoframeworkexample.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tools-undoframework.html" projectPath="tools/undoframework/undoframework.pro" name="Undo Framework">
+   <description><![CDATA[This example shows how to implement undo/redo functionality with the Qt undo framework.]]></description>
+   <tags>example,undoframework,tools</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/analogclock-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-analogclock.html" projectPath="widgets/analogclock/analogclock.pro" name="Analog Clock">
+   <description><![CDATA[The Analog Clock example shows how to draw the contents of a custom widget.]]></description>
+   <tags>example,analogclock,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/calculator-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-calculator.html" projectPath="widgets/calculator/calculator.pro" name="Calculator ">
+   <description><![CDATA[The example shows how to use signals and slots to implement the functionality of a calculator widget, and how to use <tt>QGridLayout</tt> to place child widgets in a grid.]]></description>
+   <tags>example,calculator,widgets,qgridlayout</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/calendarwidgetexample.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-calendarwidget.html" projectPath="widgets/calendarwidget/calendarwidget.pro" name="Calendar Widget">
+   <description><![CDATA[The Calendar Widget example shows use of <tt>QCalendarWidget</tt>.]]></description>
+   <tags>example,calendarwidget,widgets,qcalendarwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/charactermap-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-charactermap.html" projectPath="widgets/charactermap/charactermap.pro" name="Character Map">
+   <description><![CDATA[The Character Map example shows how to create a custom widget that can both display its own content and respond to user input.]]></description>
+   <tags>example,charactermap,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/codeeditor-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-codeeditor.html" projectPath="widgets/codeeditor/codeeditor.pro" name="Code Editor">
+   <description><![CDATA[The Code Editor example shows how to create a simple editor that has line numbers and that highlights the current line.]]></description>
+   <tags>example,codeeditor,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/digitalclock-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-digitalclock.html" projectPath="widgets/digitalclock/digitalclock.pro" name="Digital Clock">
+   <description><![CDATA[The Digital Clock example shows how to use <tt>QLCDNumber</tt> to display a number with LCD-like digits.]]></description>
+   <tags>example,digitalclock,widgets,qlcdnumber</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/groupbox-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-groupbox.html" projectPath="widgets/groupbox/groupbox.pro" name="Group Box">
+   <description><![CDATA[The Group Box example shows how to use the different kinds of group boxes in Qt.]]></description>
+   <tags>example,groupbox,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/icons-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-icons.html" projectPath="widgets/icons/icons.pro" name="Icons">
+   <description><![CDATA[The Icons example shows how <tt>QIcon</tt> can generate pixmaps reflecting an icon's state, mode and size. These pixmaps are generated from the set of pixmaps made available to the icon, and are used by Qt widgets to show an icon representing a particular action.]]></description>
+   <tags>example,icons,widgets,qicon</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/imageviewer-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-imageviewer.html" projectPath="widgets/imageviewer/imageviewer.pro" name="Image Viewer">
+   <description><![CDATA[The example shows how to combine <tt>QLabel</tt> and <tt>QScrollArea</tt> to display an image. <tt>QLabel</tt> is typically used for displaying text, but it can also display an image. <tt>QScrollArea</tt> provides a scrolling view around another widget. If the child widget exceeds the size of the frame, <tt>QScrollArea</tt> automatically provides scroll bars.]]></description>
+   <tags>example,imageviewer,widgets,qlabel,qscrollarea,qlabel,qscrollarea,qscrollarea</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/lineedits-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-lineedits.html" projectPath="widgets/lineedits/lineedits.pro" name="Line Edits">
+   <description><![CDATA[The Line Edits example demonstrates the many ways that <tt>QLineEdit</tt> can be used, and shows the effects of various properties and validators on the input and output supplied by the user.]]></description>
+   <tags>example,lineedits,widgets,qlineedit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/movie-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-movie.html" projectPath="widgets/movie/movie.pro" name="Movie Player">
+   <description><![CDATA[The Movie example demonstrates how to use <tt>QMovie</tt> and <tt>QLabel</tt> to display animations. Now that Qt comes with the <tt>Phonon multimedia framework</tt>, <tt>QMovie</tt> is mostly useful if one wants to play a simple animation without the added complexity of a multimedia framework to install and deploy.]]></description>
+   <tags>example,movie,widgets,qmovie,qlabel,phonon multimedia framework,qmovie</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/scribble-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-scribble.html" projectPath="widgets/scribble/scribble.pro" name="Scribble">
+   <description><![CDATA[The Scribble example shows how to reimplement some of <tt>QWidget</tt>'s event handlers to receive the events generated for the application's widgets.]]></description>
+   <tags>example,scribble,widgets,qwidget</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/shapedclock-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-shapedclock.html" projectPath="widgets/shapedclock/shapedclock.pro" name="Shaped Clock">
+   <description><![CDATA[The Shaped Clock example shows how to apply a widget mask to a top-level widget to produce a shaped window.]]></description>
+   <tags>example,shapedclock,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/sliders-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-sliders.html" projectPath="widgets/sliders/sliders.pro" name="Sliders">
+   <description><![CDATA[Qt provides three types of slider-like widgets: <tt>QSlider</tt>, <tt>QScrollBar</tt> and <tt>QDial</tt>. They all inherit most of their functionality from <tt>QAbstractSlider</tt>, and can in theory replace each other in an application since the differences only concern their look and feel. This example shows what they look like, how they work and how their behavior and appearance can be manipulated through their properties.]]></description>
+   <tags>example,sliders,widgets,qslider,qscrollbar,qdial,qabstractslider</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/spinboxes-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-spinboxes.html" projectPath="widgets/spinboxes/spinboxes.pro" name="Spin Boxes">
+   <description><![CDATA[The Spin Boxes example shows how to use the many different types of spin boxes available in Qt, from a simple <tt>QSpinBox</tt> widget to more complex editors like the <tt>QDateTimeEdit</tt> widget.]]></description>
+   <tags>example,spinboxes,widgets,qspinbox,qdatetimeedit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/styles-enabledwood.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-styles.html" projectPath="widgets/styles/styles.pro" name="Styles">
+   <description><![CDATA[The Styles example illustrates how to create custom widget drawing styles using Qt, and demonstrates Qt's predefined styles.]]></description>
+   <tags>example,styles,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/stylesheet-coffee-plastique.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-stylesheet.html" projectPath="widgets/stylesheet/stylesheet.pro" name="Style Sheet">
+   <description><![CDATA[The Style Sheet Example shows how to use style sheets.]]></description>
+   <tags>example,stylesheet,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/tabletexample.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-tablet.html" projectPath="widgets/tablet/tablet.pro" name="Tablet">
+   <description><![CDATA[This example shows how to use a Wacom tablet in Qt applications.]]></description>
+   <tags>example,tablet,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/tetrix-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-tetrix.html" projectPath="widgets/tetrix/tetrix.pro" name="Tetrix ">
+   <description><![CDATA[The Tetrix example is a Qt version of the classic Tetrix game.]]></description>
+   <tags>example,tetrix,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/tooltips-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-tooltips.html" projectPath="widgets/tooltips/tooltips.pro" name="Tool Tips">
+   <description><![CDATA[The Tool Tips example shows how to provide static and dynamic tool tips for an application's widgets.]]></description>
+   <tags>example,tooltips,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/wiggly-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-wiggly.html" projectPath="widgets/wiggly/wiggly.pro" name="Wiggly">
+   <description><![CDATA[The Wiggly example shows how to animate a widget using <tt>QBasicTimer</tt> and <tt>timerEvent()</tt>. In addition, the example demonstrates how to use <tt>QFontMetrics</tt> to determine the size of text on screen.]]></description>
+   <tags>example,wiggly,widgets,qbasictimer,timerevent(),qfontmetrics</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/windowflags-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/widgets-windowflags.html" projectPath="widgets/windowflags/windowflags.pro" name="Window Flags">
+   <description><![CDATA[The Window Flags example shows how to use the window flags available in Qt.]]></description>
+   <tags>example,windowflags,widgets</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/formextractor-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/webkit-formextractor.html" projectPath="webkit/formextractor/formextractor.pro" name="Form Extractor">
+   <description><![CDATA[The Form Extractor example shows how to use <tt>QWebFrame</tt> with JavaScript to extract form data.]]></description>
+   <tags>example,formextractor,webkit,qwebframe</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/previewer-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/webkit-previewer.html" projectPath="webkit/previewer/previewer.pro" name="HTML Previewer">
+   <description><![CDATA[The Previewer example shows how to use <tt>QtWebKit</tt>'s <tt>QWebView</tt> to preview HTML data written in a <tt>QPlainTextEdit</tt>.]]></description>
+   <tags>example,previewer,webkit,qtwebkit,qwebview,qplaintextedit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/fancybrowser-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/webkit-fancybrowser.html" projectPath="webkit/fancybrowser/fancybrowser.pro" name="Fancy Browser">
+   <description><![CDATA[The Fancy Browser example shows how to use jQuery with <tt>QtWebKit</tt> to create a web browser with special effects and content manipulation.]]></description>
+   <tags>example,fancybrowser,webkit,qtwebkit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/googlechat-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/webkit-googlechat.html" projectPath="webkit/googlechat/googlechat.pro" name="Google Chat">
+   <description><![CDATA[The Google Chat example shows how to use implement a simple Google Chat client with <tt>QtWebKit</tt>.]]></description>
+   <tags>example,googlechat,webkit,qtwebkit</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/saxbookmarks-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xml-saxbookmarks.html" projectPath="xml/saxbookmarks/saxbookmarks.pro" name="SAX Bookmarks">
+   <description><![CDATA[The SAX Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL) files that uses Qt's SAX-based API to read and parse the files. The DOM Bookmarks example provides an alternative way to read this type of file.]]></description>
+   <tags>example,saxbookmarks,xml</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/dombookmarks-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xml-dombookmarks.html" projectPath="xml/dombookmarks/dombookmarks.pro" name="DOM Bookmarks">
+   <description><![CDATA[The DOM Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL) files that uses Qt's DOM-based XML API to read and parse the files. The SAX Bookmarks example provides an alternative way to read this type of file.]]></description>
+   <tags>example,dombookmarks,xml</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/rsslistingexample.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xml-rsslisting.html" projectPath="xml/rsslisting/rsslisting.pro" name="RSS-Listing">
+   <description><![CDATA[This example shows how to create a widget that displays news items from RDF news sources.]]></description>
+   <tags>example,rsslisting,xml</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/xmlstreamexample-screenshot.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xml-streambookmarks.html" projectPath="xml/streambookmarks/streambookmarks.pro" name="QXmlStream Bookmarks">
+   <description><![CDATA[The QXmlStream Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL) files using Qt's <tt>QXmlStreamReader</tt> class for reading, and <tt>QXmlStreamWriter</tt> class for writing the files.]]></description>
+   <tags>example,streambookmarks,xml,qxmlstreamreader,qxmlstreamwriter</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/recipes-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xmlpatterns-recipes.html" projectPath="xmlpatterns/recipes/recipes.pro" name="Recipes">
+   <description><![CDATA[The recipes example shows how to use <tt>QtXmlPatterns</tt> to query XML data loaded from a file.]]></description>
+   <tags>example,recipes,xmlpatterns,qtxmlpatterns</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/qobjectxmlmodel-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xmlpatterns-qobjectxmlmodel.html" projectPath="xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.pro" name="QObjectXmlModel">
+   <description><![CDATA[This example shows how to use <tt>QtXmlPatterns</tt> to query <tt>QObject</tt> trees by modeling the non-XML data structure of a <tt>QObject</tt> tree to look like XML.]]></description>
+   <tags>example,qobjectxmlmodel,xmlpatterns,qtxmlpatterns,qobject,qobject</tags>
+  </example>
+  <example imageUrl="" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xmlpatterns-filetree.html" projectPath="xmlpatterns/filetree/filetree.pro" name="File Tree">
+   <description><![CDATA[This example shows how to use <tt>QtXmlPatterns</tt> for querying non-XML data that is modeled to look like XML.]]></description>
+   <tags>example,filetree,xmlpatterns,qtxmlpatterns</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/trafficinfo-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xmlpatterns-trafficinfo.html" projectPath="xmlpatterns/trafficinfo/trafficinfo.pro" name="Traffic Info">
+   <description><![CDATA[The WAP service used in this example is <tt>wap.trafikanten.no</tt> that is run by the Norwegian governmental agency for public transport in Oslo. The service provides real time information about the departure of busses, trams and undergrounds for every station in the city area.]]></description>
+   <tags>example,trafficinfo,xmlpatterns</tags>
+  </example>
+  <example imageUrl="qthelp://com.trolltech.qt/qdoc/images/schema-example.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/xmlpatterns-schema.html" projectPath="xmlpatterns/schema/schema.pro" name="XML Schema Validation">
+   <description><![CDATA[This example shows how to use <tt>QtXmlPatterns</tt> to validate XML with a W3C XML Schema.]]></description>
+   <tags>example,schema,xmlpatterns,qtxmlpatterns</tags>
+  </example>
+ </examples>
+ <tutorials>
+  <tutorial imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-part1-screenshot.png" difficulty="?" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part1.html" projectPath="tutorials/addressbook/part1/part1.pro" name="Address Book Example">
+   <steps>
+    <step imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-part1-screenshot.png" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part1.html" projectPath="tutorials/addressbook/part1/part1.pro"/>
+    <step imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-part2-add-contact.png" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part2.html" projectPath="tutorials/addressbook/part2/part2.pro"/>
+    <step imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-part3-screenshot.png" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part3.html" projectPath="tutorials/addressbook/part3/part3.pro"/>
+    <step imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-screenshot.png" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part4.html" projectPath="tutorials/addressbook/part4/part4.pro"/>
+    <step imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-part5-screenshot.png" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part5.html" projectPath="tutorials/addressbook/part5/part5.pro"/>
+    <step imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-part6-screenshot.png" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part6.html" projectPath="tutorials/addressbook/part6/part6.pro"/>
+    <step imageUrl="qthelp://com.trolltech.qt/qdoc/images/addressbook-tutorial-part7-screenshot.png" docUrl="qthelp://com.trolltech.qt/qdoc/tutorials-addressbook-part7.html" projectPath="tutorials/addressbook/part7/part7.pro"/>
+   </steps>
+   <description><![CDATA[This first part covers the design of the basic graphical user interface (GUI) for our address book application.]]></description>
+   <tags>tutorial,part1,tutorials,addressbook</tags>
+  </tutorial>
+ </tutorials>
+</instructionals>
diff --git a/share/qtcreator/welcomescreen/gettingstarted.qml b/share/qtcreator/welcomescreen/gettingstarted.qml
new file mode 100644 (file)
index 0000000..bb712c0
--- /dev/null
@@ -0,0 +1,4 @@
+import QtQuick 1.0
+import "widgets"
+
+ExampleBrowser {}
diff --git a/share/qtcreator/welcomescreen/newssupport.qml b/share/qtcreator/welcomescreen/newssupport.qml
new file mode 100644 (file)
index 0000000..55e2236
--- /dev/null
@@ -0,0 +1,7 @@
+import QtQuick 1.0
+
+Rectangle {
+    width: 200; height: 200
+    color: "blue"
+}
+
diff --git a/share/qtcreator/welcomescreen/qtcreator_tutorials.xml b/share/qtcreator/welcomescreen/qtcreator_tutorials.xml
new file mode 100644 (file)
index 0000000..d0e0a2d
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<instructionals module="Qt">
+ <tutorials>
+  <tutorial imageUrl="" difficulty="" docUrl="qthelp://com.nokia.qtcreator/doc/creator-quick-tour.html" projectPath="" name="The Qt Creator User Interface">
+   <description><![CDATA[This tutorial provides you with a principal summary of the Qt Creator User Interface and introduces fundamental terminologies.]]></description>
+   <tags>qt creator,quick tour,ui</tags>
+  </tutorial>
+  <tutorial imageUrl="" difficulty="" docUrl="qthelp://com.nokia.qtcreator/doc/creator-build-example-application.html" projectPath="" name="Building and Running an Example Application">
+   <description><![CDATA[How to verify that your installation works]]></description>
+   <tags>qt creator,build,compile</tags>
+  </tutorial>
+  <tutorial imageUrl="" difficulty="" docUrl="qthelp://com.nokia.qtcreator/doc/creator-writing-program.html" projectPath="" name="Creating a Qt C++ Application">
+   <description><![CDATA[This tutorial describes how to use Qt Creator to create a small Qt application, Text Finder.]]></description>
+   <tags>qt,c++,text,qt designer,qt creator</tags>
+  </tutorial>
+  <tutorial imageUrl="" difficulty="" docUrl="qthelp://com.nokia.qtcreator/doc/creator-mobile-example.html" projectPath="" name="Creating a Mobile Application">
+   <description><![CDATA[This tutorial describes how to use Qt Creator to create a small Qt application, that uses the System Information Mobility API to fetch battery information from the device.]]></description>
+   <tags>qt,c++,mobile,qt mobility,qt creator</tags>
+  </tutorial>
+  <tutorial imageUrl="" difficulty="" docUrl="qthelp://com.nokia.qtcreator/doc/creator-qml-application.html" projectPath="" name="Creating a Qt Quick Application">
+   <description><![CDATA[This tutorial uses basic elements and illustrates basic concepts of Qt Quick.]]></description>
+   <tags>qt quick,qml,states,transitions,visual designer,qt creator</tags>
+  </tutorial>
+ </tutorials>
+</instructionals>
diff --git a/share/qtcreator/welcomescreen/welcomescreen.pro b/share/qtcreator/welcomescreen/welcomescreen.pro
new file mode 100644 (file)
index 0000000..0e9ebeb
--- /dev/null
@@ -0,0 +1,22 @@
+TEMPLATE = subdirs
+SUBDIRS = components/styleitem
+
+OTHER_FILES = develop.qml \
+              gettingstarted.qml \
+              newssupport.qml \
+              welcomescreen.qml \
+              widgets/Button.qml \
+              widgets/Feedback.qml \
+              widgets/RatingBar.qml \
+              widgets/ExampleBrowser.qml \
+              widgets/LineEdit.qml \
+              widgets/ExampleDelegate.qml \
+              widgets/LinksBar.qml \
+              widgets/HeaderItemView.qml \
+              widgets/RecentSessions.qml \
+              widgets/RecentProjects.qml \
+              widgets/FeaturedAndNewsListing.qml \
+              widgets/NewsListing.qml \
+              widgets/TabWidget.qml \
+              examples_fallback.xml \
+              qtcreator_tutorials.xml
diff --git a/share/qtcreator/welcomescreen/welcomescreen.qml b/share/qtcreator/welcomescreen/welcomescreen.qml
new file mode 100644 (file)
index 0000000..67a5a3a
--- /dev/null
@@ -0,0 +1,91 @@
+import Qt 4.7
+import "widgets"
+
+Image {
+    id: root
+    source: "qrc:welcome/images/welcomebg.png"
+
+    // work around the fact that we can't use
+    // a property alias to welcomeMode.activePlugin
+    property int current: 0
+    onCurrentChanged: welcomeMode.activePlugin = current
+    Component.onCompleted: current = welcomeMode.activePlugin
+
+    BorderImage {
+        id: headerLine
+        anchors.top: parent.top
+        anchors.left: parent.left
+        anchors.right: parent.right
+        // FIXME: 25 px and get rid of border
+        height: 24
+        border { top: 1; bottom: 1}
+        source: "qrc:welcome/images/tab_inactive.png"
+    }
+    BorderImage {
+        id: inner_background
+        Image {
+            id: header;
+            source: "qrc:welcome/images/center_frame_header.png";
+            anchors.verticalCenter: parent.verticalCenter;
+            anchors.left: parent.left;
+            anchors.topMargin: 2
+        }
+        anchors.top: headerLine.bottom
+        source: "qrc:welcome/images/background_center_frame_v2.png"
+        width: parent.width
+        height: 60
+        border.right: 2
+        border.left: 2
+        border.top: 2
+        border.bottom: 10
+    }
+
+    LinksBar {
+        id: navigationAndDevLinks
+        property alias current: root.current
+        anchors.top: inner_background.bottom
+        anchors.left: parent.left
+        anchors.bottomMargin: 4
+        anchors.topMargin: -2
+        width: parent.width
+        model: tabs.model
+        tabBarWidth: width
+    }
+
+    BorderImage {
+        id: news
+        opacity: 0.7
+        source: "qrc:welcome/images/rc_combined.png"
+        border.left: 5; border.top: 5
+        border.right: 5; border.bottom: 5
+        anchors.top: navigationAndDevLinks.bottom
+        anchors.bottom: feedback.top
+        anchors.left: parent.left
+        anchors.margins: 5
+        width: 270
+        FeaturedAndNewsListing {
+            anchors.fill: parent
+            anchors.margins: 4
+        }
+
+    }
+
+    TabWidget {
+        id: tabs
+        property int current: root.current
+        model: pagesModel
+        anchors.top: navigationAndDevLinks.bottom
+        anchors.bottom: feedback.top
+        anchors.left: news.right
+        anchors.right: parent.right
+        anchors.leftMargin: 0
+        anchors.margins: 4
+    }
+
+    Feedback {
+        id: feedback
+        anchors.bottom: parent.bottom
+        width: parent.width
+    }
+
+}
diff --git a/share/qtcreator/welcomescreen/widgets/Button.qml b/share/qtcreator/welcomescreen/widgets/Button.qml
new file mode 100644 (file)
index 0000000..40bd870
--- /dev/null
@@ -0,0 +1,45 @@
+import Qt 4.7
+
+BorderImage {
+    property string text
+    property string image
+    property int iconSize : innerImg.sourceSize.height
+    signal clicked;
+    id: root
+    source: "qrc:/welcome/images/btn_26.png"
+    height: innerImg.height + 16
+
+    border.left: 5; border.top: 5
+    border.right: 5; border.bottom: 5
+
+    Image{
+        id: innerImg
+        height: root.iconSize
+        width: root.iconSize
+        anchors.verticalCenter: label.verticalCenter
+        anchors.right: label.left
+        anchors.rightMargin: 4
+        visible: root.image != ""
+        source: root.image
+    }
+
+    Text {
+        id: label;
+        anchors.left: innerImg.right
+        anchors.right: parent.right
+        text: root.text
+    }
+
+    MouseArea { id: mouseArea; anchors.fill: parent; hoverEnabled: true; onClicked: root.clicked() }
+
+    states: [
+        State {
+            id: pressedState; when: mouseArea.pressed;
+            PropertyChanges { target: root; source: "qrc:/welcome/images/btn_26_pressed.png" }
+        },
+        State {
+            id: hoverState; when: mouseArea.containsMouse
+            PropertyChanges { target: root; source: "qrc:/welcome/images/btn_26_hover.png" }
+        }
+    ]
+}
diff --git a/share/qtcreator/welcomescreen/widgets/ExampleBrowser.qml b/share/qtcreator/welcomescreen/widgets/ExampleBrowser.qml
new file mode 100644 (file)
index 0000000..327af9d
--- /dev/null
@@ -0,0 +1,186 @@
+import QtQuick 1.0
+import "../components" as Components
+
+Item {
+    id: exampleBrowserRoot
+    Item {
+        id : lineEditRoot
+        width: parent.width
+        height: lineEdit.height
+
+        Connections {
+            target: gettingStarted
+            onTagsUpdated: {
+                var tagList = gettingStarted.tagList()
+                for (var tag in tagList) {
+                    tagsTestModel.append({ "text": tagList[tag], "value": tagList[tag] });
+                }
+            }
+        }
+
+        Components.TextField {
+            Behavior on width { NumberAnimation{} }
+            placeholderText: !checkBox.checked ? qsTr("Search in Tutorials") : qsTr("Search in Tutorials, Examples and Demos")
+            focus: true
+            id: lineEdit
+            width: lineEditRoot.width - checkBox.width - 20 - tagFilterButton.width
+            onTextChanged: examplesModel.filterRegExp = RegExp('.*'+text, "im")
+        }
+
+        ListModel {
+            id: tagsTestModel
+        }
+
+        Components.CheckBox {
+            id: checkBox
+            text: qsTr("Show Examples and Demos")
+            checked: false
+            anchors.left: lineEdit.right
+            anchors.verticalCenter: lineEdit.verticalCenter
+            height: lineEdit.height
+            onCheckedChanged: examplesModel.showTutorialsOnly = !checked;
+        }
+
+        Components.Button {
+            id: tagFilterButton
+            property string tag
+            Behavior on width { NumberAnimation{} }
+            onTagChanged: { examplesModel.filterTag = tag; examplesModel.updateFilter() }
+            anchors.left: checkBox.right
+            anchors.verticalCenter: lineEdit.verticalCenter
+            visible: !examplesModel.showTutorialsOnly
+            text: tag === "" ? qsTr("Filter by Tag") : qsTr("Tag Filter: ") + tag
+            onClicked: tagChooser.visible = !tagChooser.visible
+        }
+    }
+    Components.ScrollArea  {
+        id: scrollArea
+        anchors.topMargin: lineEditRoot.height
+        anchors.fill: parent
+        clip: true
+        frame: false
+        Column {
+            Repeater {
+                id: repeater
+                model: examplesModel
+                delegate: ExampleDelegate { width: scrollArea.width-20 }
+            }
+        }
+    }
+
+
+    Rectangle {
+        id: tagChooser
+        anchors.fill: parent
+        color: "darkgrey"
+        visible: false
+        opacity: 0.95
+        radius: 6
+        MouseArea { anchors.fill: parent; hoverEnabled: true } // disable mouse on background
+        Text {
+            id: descr;
+            anchors.margins: 6;
+            color: "white";
+            text: qsTr("Please choose a tag to filter for:");
+            anchors.top: parent.top;
+            anchors.left: parent.left
+            font.bold: true
+        }
+
+        Item {
+            width: rect.width
+            height: rect.height
+
+            anchors.margins: 6;
+            anchors.top: parent.top;
+            anchors.right: parent.right
+
+            Rectangle {
+                color: "red"
+                id: rect
+                radius: 4
+                opacity: 0.3
+                width: closeText.width+4
+                height: closeText.height+4
+                x: closeText.x-2
+                y: closeText.y-2
+            }
+            Text { id: closeText; text: qsTr("Close"); color: "white"; anchors.centerIn: parent }
+            MouseArea {
+                id: mouseArea
+                anchors.fill: parent
+                hoverEnabled: true
+                onClicked: {
+                    tagChooser.visible = false;
+                    tagFilterButton.tag = "";
+                }
+            }
+        }
+
+        Flickable {
+            id: flickable
+            anchors.fill: parent
+            anchors.margins: 6
+            anchors.topMargin: descr.height + anchors.margins*2
+            contentHeight: flow.height
+            contentWidth: flow.width
+            flickableDirection: Flickable.VerticalFlick
+            clip: true
+            Flow {
+                width: tagChooser.width
+                id: flow
+                spacing: 6
+                Repeater {
+                    model: tagsTestModel
+                    delegate: Item {
+                        width: btnRect.width
+                        height: btnRect.height
+                        Rectangle {
+                            id: btnRect
+                            radius: 4
+                            opacity: 0
+                            width: closeText.width+4
+                            height: closeText.height+4
+                            x: closeText.x-2
+                            y: closeText.y-2
+                        }
+                        Text { id: closeText; text: model.text; color: "white"; anchors.centerIn: parent }
+                        MouseArea {
+                            id: mouseArea
+                            anchors.fill: parent
+                            hoverEnabled: true
+                        }
+
+                        states: [
+                            State {
+                                name: "selected"
+                                when: mouseArea.pressed
+                            },
+                            State {
+                                name: "hovered"
+                                when: mouseArea.containsMouse
+                                PropertyChanges {
+                                    target: btnRect
+                                    color: "darkblue"
+                                    opacity: 0.3
+                                }
+                            }
+                        ]
+                        transitions: [
+                            Transition {
+                                from: "hovered"
+                                to: "selected"
+                                ParallelAnimation {
+                                    PropertyAction { target: tagFilterButton; property: "tag"; value: model.value }
+                                    PropertyAction { target: tagChooser; property: "visible"; value: false }
+                                    ColorAnimation { to: "#00000000"; duration: 0 }
+                                }
+                            }
+                        ]
+                    }
+                }
+            }
+
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml b/share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml
new file mode 100644 (file)
index 0000000..f66a2e4
--- /dev/null
@@ -0,0 +1,75 @@
+import QtQuick 1.0
+
+Rectangle {
+    id: root
+    height: 110
+    color: "#00ffffff"
+    radius: 6
+
+    Text {
+        id: title
+        anchors.left: parent.left
+        anchors.leftMargin: 10
+        anchors.top: parent.top
+        anchors.topMargin: 10
+        text: model.name
+        font.bold: true
+        font.pixelSize: 16;
+
+    }
+
+    RatingBar { id: rating; anchors.top: parent.top; anchors.topMargin: 10; anchors.right: parent.right; anchors.rightMargin: 10; rating: model.difficulty; visible: model.difficulty !== 0 }
+
+    Image {
+        property bool hideImage : model.imageUrl === "" || status === Image.Error
+        id: image
+        anchors.top: title.bottom
+        anchors.left: parent.left
+        anchors.topMargin: 10
+        anchors.leftMargin: 10
+        width: hideImage ? 0 : 90
+        height: hideImage ? 0 : 66
+        asynchronous: true
+        fillMode: Image.PreserveAspectFit
+        source: model.imageUrl !== "" ? "image://helpimage/" + encodeURI(model.imageUrl) : ""
+    }
+
+    Text {
+        id: description
+        clip: true
+        anchors.left: image.right
+        anchors.leftMargin: 10
+        anchors.right: parent.right
+        anchors.rightMargin: 10
+        anchors.top: rating.bottom
+        anchors.topMargin: 6
+        wrapMode: Text.WordWrap
+        text: model.description
+    }
+    Text { id: labelText; anchors.top: description.bottom; anchors.topMargin: 10; anchors.left: image.right; text: "Tags: "; font.bold: true; }
+    Row { id: tagLine; anchors.top: description.bottom; anchors.topMargin: 10; anchors.left: labelText.right; Text { text: model.tags.join(", "); color: "grey" } }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        hoverEnabled: true
+        onClicked: {
+            if (model.hasSourceCode)
+                gettingStarted.openProject(model.projectPath, model.filesToOpen, model.docUrl)
+            else
+                gettingStarted.openSplitHelp(model.docUrl);
+        }
+        onEntered: parent.state = "hover"
+        onExited: parent.state = ""
+    }
+
+    states: [ State { name: "hover"; PropertyChanges { target: root; color: "#eeeeeeee" } } ]
+
+    transitions:
+        Transition {
+        from: ""
+        to: "hover"
+        reversible: true
+        ColorAnimation { duration: 100; easing.type: Easing.OutQuad }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/FeaturedAndNewsListing.qml b/share/qtcreator/welcomescreen/widgets/FeaturedAndNewsListing.qml
new file mode 100644 (file)
index 0000000..c545b7a
--- /dev/null
@@ -0,0 +1,39 @@
+import QtQuick 1.0
+import "../components" as Components
+Item {
+    InsetText {
+        id: text
+        anchors.horizontalCenter: parent.horizontalCenter
+        anchors.top:  parent.top
+        anchors.margins: 10
+        horizontalAlignment: Text.AlignHCenter
+        text: "Featured News"
+//        mainColor: "#44A51C"
+        mainColor: "#074C1C"
+        font.bold: true
+        font.pointSize: 16
+    }
+
+    ListModel {
+        id: tempNewsModel
+        ListElement { title: "Loading news sources..."; description: "Loading..." ; blogIcon: ""; blogName: ""; link: "" }
+    }
+
+    NewsListing {
+        id: newsList
+        model: {
+            if (aggregatedFeedsModel.articleCount > 0)
+                return aggregatedFeedsModel
+            else
+                return tempNewsModel
+        }
+        anchors.bottom: parent.bottom
+        anchors.top: text.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.topMargin: text.height
+        clip: true
+
+    }
+
+}
diff --git a/share/qtcreator/welcomescreen/widgets/Feedback.qml b/share/qtcreator/welcomescreen/widgets/Feedback.qml
new file mode 100644 (file)
index 0000000..71fc1e7
--- /dev/null
@@ -0,0 +1,56 @@
+import Qt 4.7
+import "../components" as Components
+
+BorderImage {
+    id: inner_background
+    height: openProjectButton.height + 10
+    source: "qrc:welcome/images/background_center_frame_v2.png"
+    border.left: 2
+    border.right: 2
+
+    Rectangle { color: "black"; width: parent.width; height: 1; anchors.top: parent.top; anchors.left: parent.left }
+
+    Components.Button {
+
+        id: openProjectButton
+        text: "Open Project"
+        iconSource: "image://desktoptheme/document-open"
+        onClicked: welcomeMode.openProject();
+        height: 32
+        anchors.left: parent.left
+        anchors.margins: 5
+        anchors.verticalCenter: parent.verticalCenter
+    }
+
+    Components.Button {
+        id: createProjectButton
+        text: "Create Project"
+        iconSource: "image://desktoptheme/document-new"
+        onClicked: welcomeMode.newProject();
+        height: 32
+        anchors.left: openProjectButton.right
+        anchors.margins: 5
+        anchors.verticalCenter: parent.verticalCenter
+    }
+
+
+    Components.Button {
+        id: feedbackButton
+        text: "Feedback"
+        iconSource: "qrc:welcome/images/feedback_arrow.png"
+        height: 32
+        anchors.verticalCenter: parent.verticalCenter
+        anchors.right: feedbackText.left
+        anchors.margins: 5
+        onClicked: welcomeMode.sendFeedback()
+    }
+
+    Text {
+        id: feedbackText
+        anchors.verticalCenter: parent.verticalCenter
+        anchors.right: parent.right
+        anchors.leftMargin: 10
+        anchors.margins: 5
+        text: "Help us make Qt Creator even better"
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/HeaderItemView.qml b/share/qtcreator/welcomescreen/widgets/HeaderItemView.qml
new file mode 100644 (file)
index 0000000..1ac0079
--- /dev/null
@@ -0,0 +1,34 @@
+import QtQuick 1.0
+Item {
+    id: root
+    height: childrenRect.height
+    property string header
+    property QtObject model
+    property Component delegate
+
+    Text {
+        id: titleText
+        text: root.header
+        font.bold: true
+        font.pointSize: 14
+        color: "#555555"
+        anchors.top: parent.top
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.topMargin: 6
+    }
+
+    Column {
+        id: dataSection
+        spacing: 10
+        anchors.topMargin: 10
+        anchors.top: titleText.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+
+        Repeater {
+            model: root.model
+            delegate: root.delegate
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/InsetText.qml b/share/qtcreator/welcomescreen/widgets/InsetText.qml
new file mode 100644 (file)
index 0000000..0a271bf
--- /dev/null
@@ -0,0 +1,15 @@
+import QtQuick 1.0
+
+Text {
+    property color mainColor: "darkgrey"
+    Text {
+        x: 0; y: -1
+        text: parent.text
+        color: parent.mainColor
+        font.bold: parent.font.bold
+        font.pointSize: parent.font.pointSize
+        font.italic: parent.font.italic
+    }
+    text: "Featured News"
+    color: "white"
+}
diff --git a/share/qtcreator/welcomescreen/widgets/LineEdit.qml b/share/qtcreator/welcomescreen/widgets/LineEdit.qml
new file mode 100644 (file)
index 0000000..9d3654d
--- /dev/null
@@ -0,0 +1,30 @@
+import QtQuick 1.0
+
+FocusScope {
+    id: root
+    signal textChanged
+    property alias text : input.text
+    height:input.font.pixelSize*1.8
+    BorderImage {
+        anchors.fill: parent
+        source: "img/lineedit.png"
+        border.left: 5; border.top: 5
+        border.right: 5; border.bottom: 5
+        TextInput {
+            id: input
+            anchors.verticalCenter: parent.verticalCenter
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.leftMargin: 4
+            anchors.rightMargin: 4
+            property string defaultText: "Click here to search the tutorials and howtos"
+            color: "grey"
+            text:  defaultText
+            font.pointSize: 12
+            clip: true
+            onActiveFocusChanged: activeFocus ? state = 'active' : state = ''
+            onTextChanged: if (text != defaultText) root.textChanged();
+            states: [ State { name: "active"; PropertyChanges { target: input; color: "black"; text: "" } } ]
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/LinksBar.qml b/share/qtcreator/welcomescreen/widgets/LinksBar.qml
new file mode 100644 (file)
index 0000000..a4efb74
--- /dev/null
@@ -0,0 +1,59 @@
+import QtQuick 1.0
+
+
+Row {
+    id: tabBar
+    height: 25
+
+    property alias model: tabs.model
+    property int tabBarWidth
+
+    Repeater {
+        id: tabs
+        height: tabBar.height
+        model: parent.model
+        delegate:
+            Item {
+            width: tabBarWidth / tabs.count
+            height: tabBar.height
+
+            Rectangle {
+                width: parent.width; height: 1
+                anchors { bottom: parent.bottom; bottomMargin: 1 }
+                color: "#acb2c2"
+            }
+            BorderImage {
+                id: tabBackground
+                anchors.fill: parent
+                border { top: 1; bottom: 1}
+                source: "qrc:welcome/images/tab_inactive.png"
+            }
+            Text {
+                id: text
+                horizontalAlignment: Qt.AlignHCenter; verticalAlignment: Qt.AlignVCenter
+                anchors.fill: parent
+                text: model.modelData.title
+                elide: Text.ElideRight
+                color: "white"
+            }
+            MouseArea {
+                id: mouseArea
+                hoverEnabled: true
+                anchors.fill: parent
+                onClicked: tabBar.current = index
+            }
+            states: [
+                State {
+                    id: activeState; when: tabBar.current == index
+                    PropertyChanges { target: tabBackground; source:"qrc:welcome/images/tab_active.png" }
+                    PropertyChanges { target: text; color: "black" }
+                },
+                State {
+                    id: hoverState; when: mouseArea.containsMouse
+                    PropertyChanges { target: tabBackground; source:"qrc:welcome/images/tab_hover.png" }
+                }
+
+            ]
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/NewsListing.qml b/share/qtcreator/welcomescreen/widgets/NewsListing.qml
new file mode 100644 (file)
index 0000000..7ccc33d
--- /dev/null
@@ -0,0 +1,73 @@
+import Qt 4.7
+
+Item {
+    id: root
+
+    property int currentItem: 0
+    property alias model: repeater.model
+    property alias itemCount: repeater.count
+
+    Timer {
+        id: timer
+        repeat: true
+        interval: 30*1000
+        onTriggered: repeater.incrementIndex()
+    }
+
+    Repeater {
+        id: repeater
+        function incrementIndex() {
+            repeater.itemAt(currentItem).active = false
+            currentItem = (currentItem+1) % repeater.count
+            repeater.itemAt(currentItem).active = true
+        }
+
+        function handleModelChanged() {
+            if (timer.running)
+                timer.stop();
+            currentItem = 0
+            //FIXME: this doesn't work
+            repeater.itemAt(currentItem).active = true
+            timer.start()
+        }
+
+        anchors.fill: parent
+        onModelChanged: handleModelChanged()
+        delegate: Item {
+            property bool active: false
+            id: delegateItem
+            opacity: 0
+            height: root.height
+            width: 270
+            Column {
+                spacing: 10
+                width: parent.width
+                id: column
+                Text { id: heading1; text: title; font.bold: true; wrapMode: Text.WrapAtWordBoundaryOrAnywhere; textFormat: Text.RichText; width: parent.width-icon.width-5 }
+                Row {
+                    spacing: 5
+                    width: parent.width
+                    Image { id: icon; source: blogIcon; asynchronous: true }
+                    Text { id: heading2; text: blogName; font.italic: true; wrapMode: Text.WrapAtWordBoundaryOrAnywhere; textFormat: Text.RichText; width: parent.width-icon.width-5 }
+                }
+                Text { id: text; text: description; wrapMode: Text.WrapAtWordBoundaryOrAnywhere; textFormat: Text.RichText ; width: parent.width-10 }
+                Text { visible: link !== ""; id: readmore; text: qsTr("Click to read more..."); font.italic: true; wrapMode: Text.WrapAtWordBoundaryOrAnywhere; textFormat: Text.RichText }
+            }
+            MouseArea { anchors.fill: parent; onClicked: Qt.openUrlExternally(link); hoverEnabled: true; id: mouseArea }
+
+            StateGroup {
+                id: activeState
+                states: [ State { name: "active"; when: delegateItem.active; PropertyChanges { target: delegateItem; opacity: 1 } } ]
+                transitions: [
+                    Transition { from: ""; to: "active"; reversible: true; NumberAnimation { target: delegateItem; property: "opacity"; duration: 200 } }
+                ]
+            }
+
+            states: [
+                State { name: "clicked"; when: mouseArea.pressed;  PropertyChanges { target: text; color: "black" } },
+                State { name: "hovered"; when: mouseArea.containsMouse;  PropertyChanges { target: text; color: "#074C1C" } }
+            ]
+
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/RatingBar.qml b/share/qtcreator/welcomescreen/widgets/RatingBar.qml
new file mode 100644 (file)
index 0000000..f7d5a67
--- /dev/null
@@ -0,0 +1,9 @@
+import QtQuick 1.0
+
+Row {
+    property int rating : 2
+    property int totalRating: 3
+
+    Repeater { id: rep1; model: rating; Image { source: "img/face-star.png"; width: 22 } }
+    Repeater { id: rep2; model: totalRating-rating; Image { source: "img/draw-star.png"; width: 22 } }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/RecentProjects.qml b/share/qtcreator/welcomescreen/widgets/RecentProjects.qml
new file mode 100644 (file)
index 0000000..8a9bab3
--- /dev/null
@@ -0,0 +1,48 @@
+import QtQuick 1.0
+import "../components" as Components
+
+HeaderItemView {
+    header: qsTr("Recently Edited Projects")
+    model: projectList
+    delegate: Item {
+        Components.QStyleItem { id: styleItem; cursor: "pointinghandcursor"; anchors.fill: parent }
+        height: nameText.font.pixelSize*2.5
+        width: dataSection.width
+        Image{
+            id: arrowImage;
+            source: "qrc:welcome/images/list_bullet_arrow.png";
+            anchors.verticalCenter: parent.verticalCenter;
+            anchors.left: parent.left
+        }
+
+        Text {
+            id: nameText
+            text: displayName
+            font.bold: true
+            width: parent.width
+            anchors.top: parent.top
+            anchors.left: arrowImage.right
+            anchors.leftMargin: 10
+        }
+
+        Text {
+            text: prettyFilePath
+            elide: Text.ElideMiddle
+            color: "grey"
+            width: parent.width
+            anchors.top: nameText.bottom
+            anchors.left: arrowImage.right
+            anchors.leftMargin: 10
+        }
+
+        Timer { id: timer; interval: 500; onTriggered: styleItem.showToolTip(filePath) }
+
+        MouseArea {
+            anchors.fill: parent
+            onClicked: projectWelcomePage.requestProject(filePath)
+            hoverEnabled: true
+            onEntered:timer.start()
+            onExited: timer.stop()
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/RecentSessions.qml b/share/qtcreator/welcomescreen/widgets/RecentSessions.qml
new file mode 100644 (file)
index 0000000..6956df9
--- /dev/null
@@ -0,0 +1,48 @@
+import QtQuick 1.0
+import "../components" as Components
+
+HeaderItemView {
+    header: qsTr("Recently Used Sessions")
+    model: sessionList
+
+    delegate: Item {
+        height: arrowImage.height
+        width: dataSection.width
+
+        function fullSessionName()
+        {
+            var newSessionName = sessionName
+            if (model.currentSession)
+                newSessionName +=  qsTr(" (current session)");
+            return newSessionName;
+        }
+
+        Image{
+            id: arrowImage;
+            source: "qrc:welcome/images/list_bullet_arrow.png";
+            anchors.verticalCenter: parent.verticalCenter;
+            anchors.left: parent.left
+        }
+
+        Text {
+            Components.QStyleItem { id: styleItem; cursor: "pointinghandcursor"; anchors.fill: parent }
+            id: fileNameText
+            text: parent.fullSessionName()
+            font.italic: model.defaultSession
+            elide: Text.ElideMiddle
+            anchors.left: arrowImage.right
+            anchors.verticalCenter: parent.verticalCenter
+            anchors.leftMargin: 10
+        }
+
+        Timer { id: timer; interval: 500; onTriggered: { styleItem.showToolTip(sessionName); print("triggered")} }
+
+        MouseArea {
+            anchors.fill: parent
+            onClicked: projectWelcomePage.requestSession(sessionName)
+            hoverEnabled: true
+            onEntered:timer.start()
+            onExited: timer.stop()
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/TabWidget.qml b/share/qtcreator/welcomescreen/widgets/TabWidget.qml
new file mode 100644 (file)
index 0000000..cf90dfe
--- /dev/null
@@ -0,0 +1,30 @@
+import Qt 4.7
+
+Item {
+    id: tabWidget
+    property alias model: contentRepeater.model
+
+    Item {
+        id: stack
+
+        anchors.margins: 0
+        width: parent.width
+        height: parent.height
+
+        Repeater {
+            id: contentRepeater
+            Loader {
+                id: pageLoader
+                clip: true
+                opacity: index == tabWidget.current
+                anchors.fill: parent
+                anchors.margins: 4
+                source: model.modelData.pageLocation
+
+                onStatusChanged: {
+                    if (pageLoader.status == Loader.Error) console.debug(source + ' failed to load')
+                }
+            }
+        }
+    }
+}
diff --git a/share/qtcreator/welcomescreen/widgets/img/draw-star.png b/share/qtcreator/welcomescreen/widgets/img/draw-star.png
new file mode 100644 (file)
index 0000000..bde0156
Binary files /dev/null and b/share/qtcreator/welcomescreen/widgets/img/draw-star.png differ
diff --git a/share/qtcreator/welcomescreen/widgets/img/face-star.png b/share/qtcreator/welcomescreen/widgets/img/face-star.png
new file mode 100644 (file)
index 0000000..7455f9d
Binary files /dev/null and b/share/qtcreator/welcomescreen/widgets/img/face-star.png differ
diff --git a/share/qtcreator/welcomescreen/widgets/img/lineedit.png b/share/qtcreator/welcomescreen/widgets/img/lineedit.png
new file mode 100644 (file)
index 0000000..1f15c4f
Binary files /dev/null and b/share/qtcreator/welcomescreen/widgets/img/lineedit.png differ
index 69509a0..df8f06e 100644 (file)
@@ -1,3 +1,4 @@
 TEMPLATE = subdirs
 SUBDIRS = qtcreator/static.pro \
-          qtcreator/translations
+          qtcreator/translations \
+          qtcreator/welcomescreen
index 25c8474..dc3f22e 100644 (file)
@@ -193,12 +193,16 @@ int main(int argc, char **argv)
     setrlimit(RLIMIT_NOFILE, &rl);
 #endif
 
+#ifdef Q_WS_X11
+    // QML is unusable with the xlib backend
+    QApplication::setGraphicsSystem("raster");
+#endif
+
     SharedTools::QtSingleApplication app((QLatin1String(appNameC)), argc, argv);
 
     const int threadCount = QThreadPool::globalInstance()->maxThreadCount();
     QThreadPool::globalInstance()->setMaxThreadCount(qMax(4, 2 * threadCount));
 
-
 #ifdef ENABLE_QT_BREAKPAD
     QtSystemExceptionHandler systemExceptionHandler;
 #endif
index adfd496..d2dd612 100644 (file)
 #define IWELCOMEPAGE_H
 
 
+#include <QtCore/QObject>
+#include <QtCore/QMetaType>
+
 #include "utils_global.h"
 
-#include <QtCore/QObject>
+QT_BEGIN_NAMESPACE
+class QDeclarativeEngine;
+QT_END_NAMESPACE
 
 namespace Utils {
 
@@ -46,13 +51,18 @@ class QTCREATOR_UTILS_EXPORT IWelcomePage : public QObject
 {
     Q_OBJECT
 
+    Q_PROPERTY(QString title READ title CONSTANT)
+    Q_PROPERTY(QString pageLocation READ pageLocation CONSTANT)
+    Q_PROPERTY(int priority READ priority CONSTANT)
+
 public:
     IWelcomePage();
     virtual ~IWelcomePage();
 
-    virtual QWidget *page() = 0;
+    virtual QString pageLocation() const = 0;
     virtual QString title() const = 0;
     virtual int priority() const { return 0; }
+    virtual void facilitateQml(QDeclarativeEngine *) {}
 
 private:
     // not used atm
index ac6ffa5..1eb6b5a 100644 (file)
@@ -48,7 +48,6 @@ SOURCES += $$PWD/environment.cpp \
     $$PWD/checkablemessagebox.cpp \
     $$PWD/styledbar.cpp \
     $$PWD/stylehelper.cpp \
-    $$PWD/welcomemodetreewidget.cpp \
     $$PWD/iwelcomepage.cpp \
     $$PWD/fancymainwindow.cpp \
     $$PWD/detailsbutton.cpp \
@@ -141,7 +140,6 @@ HEADERS += $$PWD/environment.h \
     $$PWD/qtcassert.h \
     $$PWD/styledbar.h \
     $$PWD/stylehelper.h \
-    $$PWD/welcomemodetreewidget.h \
     $$PWD/iwelcomepage.h \
     $$PWD/fancymainwindow.h \
     $$PWD/detailsbutton.h \
index 0547ad6..c1258aa 100644 (file)
@@ -84,14 +84,15 @@ SOURCES += mainwindow.cpp \
     outputpanemanager.cpp \
     navigationsubwidget.cpp \
     sidebarwidget.cpp \
-    rssfetcher.cpp \
     externaltool.cpp \
     dialogs/externaltoolconfig.cpp \
     toolsettings.cpp \
     variablechooser.cpp \
     mimetypemagicdialog.cpp \
     mimetypesettings.cpp \
-    dialogs/promptoverwritedialog.cpp
+    dialogs/promptoverwritedialog.cpp \
+    multifeedrssmodel.cpp \
+    networkaccessmanager.cpp
 
 HEADERS += mainwindow.h \
     editmode.h \
@@ -177,14 +178,15 @@ HEADERS += mainwindow.h \
     outputpanemanager.h \
     navigationsubwidget.h \
     sidebarwidget.h \
-    rssfetcher.h \
     externaltool.h \
     dialogs/externaltoolconfig.h \
     toolsettings.h \
     variablechooser.h \
     mimetypemagicdialog.h \
     mimetypesettings.h \
-    dialogs/promptoverwritedialog.h
+    dialogs/promptoverwritedialog.h \
+    multifeedrssmodel.h \
+    networkaccessmanager.h
 
 FORMS += dialogs/newdialog.ui \
     actionmanager/commandmappings.ui \
index e7782b8..234ad7e 100644 (file)
@@ -432,6 +432,10 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
     connect(m_tabBar, SIGNAL(currentChanged(int)), this, SLOT(showWidget(int)));
 }
 
+void FancyTabWidget::setSelectionWidgetHidden(bool hidden) {
+    m_selectionWidget->setHidden(hidden);
+}
+
 void FancyTabWidget::insertTab(int index, QWidget *tab, const QIcon &icon, const QString &label)
 {
     m_modesStack->insertWidget(index, tab);
index 164cf77..cc15e8b 100644 (file)
@@ -168,6 +168,7 @@ signals:
 
 public slots:
     void setCurrentIndex(int index);
+    void setSelectionWidgetHidden(bool hidden);
 
 private slots:
     void showWidget(int index);
index 724a938..b89e5c5 100644 (file)
@@ -331,6 +331,11 @@ void ModeManager::setFocusToCurrentMode()
     }
 }
 
+void ModeManager::setModeBarHidden(bool hidden)
+{
+    d->m_modeStack->setSelectionWidgetHidden(hidden);
+}
+
 ModeManager *ModeManager::instance()
 {
     return ModeManagerPrivate::m_instance;
index 1bd332f..ef9d4a9 100644 (file)
@@ -70,6 +70,7 @@ public:
     void addWidget(QWidget *widget);
 
     void activateModeType(const QString &type);
+    void setModeBarHidden(bool hidden);
 
 signals:
     void currentModeAboutToChange(Core::IMode *mode);
diff --git a/src/plugins/coreplugin/multifeedrssmodel.cpp b/src/plugins/coreplugin/multifeedrssmodel.cpp
new file mode 100644 (file)
index 0000000..66fe948
--- /dev/null
@@ -0,0 +1,190 @@
+#include "multifeedrssmodel.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QThread>
+#include <QtCore/QXmlStreamReader>
+#include <QtCore/QCoreApplication>
+
+#include <QtNetwork/QNetworkRequest>
+#include <QtNetwork/QNetworkReply>
+#include "networkaccessmanager.h"
+
+#include <QDebug>
+
+namespace Core {
+
+namespace Internal {
+
+QString shortenHtml(QString html)
+{
+    html.replace(QLatin1String("<a"), QLatin1String("<i"));
+    html.replace(QLatin1String("</a"), QLatin1String("</i"));
+    uint firstParaEndXhtml = (uint) html.indexOf(QLatin1String("</p>"));
+    uint firstParaEndHtml = (uint) html.indexOf(QLatin1String("<p>"), html.indexOf(QLatin1String("<p>"))+1);
+    uint firstParaEndBr = (uint) html.indexOf(QLatin1String("<br"));
+    uint firstParaEnd = qMin(firstParaEndXhtml, firstParaEndHtml);
+    firstParaEnd = qMin(firstParaEnd, firstParaEndBr);
+    return html.left(firstParaEnd);
+}
+
+class RssReader {
+public:
+    Internal::RssItem parseItem() {
+        RssItem item;
+        item.source = requestUrl;
+        item.blogIcon = blogIcon;
+        item.blogName = blogName;
+        while (!streamReader.atEnd()) {
+            switch (streamReader.readNext()) {
+            case QXmlStreamReader::StartElement:
+                if (streamReader.name() == QLatin1String("title"))
+                    item.title = streamReader.readElementText();
+                else if (streamReader.name() == QLatin1String("link"))
+                    item.link = streamReader.readElementText();
+                else if (streamReader.name() == QLatin1String("pubDate")) {
+                    QString dateStr = streamReader.readElementText();
+                    // fixme: honor time zone!
+                    dateStr = dateStr.left(dateStr.indexOf('+')-1);
+                    item.pubDate = QDateTime::fromString(dateStr, "ddd, dd MMM yyyy HH:mm:ss");
+                }
+                else if (streamReader.name() == QLatin1String("description"))
+                    item.description = shortenHtml(streamReader.readElementText());
+                break;
+            case QXmlStreamReader::EndElement:
+                if (streamReader.name() == QLatin1String("item"))
+                    return item;
+                break;
+            default:
+                break;
+
+            }
+        }
+        return RssItem();
+    }
+
+    Internal::RssItemList parse(QNetworkReply *reply) {
+        QUrl source = reply->request().url();
+        requestUrl = source.toString();
+        streamReader.setDevice(reply);
+        Internal::RssItemList list;
+        while (!streamReader.atEnd()) {
+            switch (streamReader.readNext()) {
+            case QXmlStreamReader::StartElement:
+                if (streamReader.name() == QLatin1String("item"))
+                    list.append(parseItem());
+                else if (streamReader.name() == QLatin1String("title"))
+                    blogName = streamReader.readElementText();
+                else if (streamReader.name() == QLatin1String("link")) {
+                    if (!streamReader.namespaceUri().isEmpty())
+                        break;
+                    QString favIconString(streamReader.readElementText());
+                    QUrl favIconUrl(favIconString);
+                    favIconUrl.setPath(QLatin1String("favicon.ico"));
+                    blogIcon = favIconUrl.toString();
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        return list;
+    }
+
+private:
+    QXmlStreamReader streamReader;
+    QString requestUrl;
+    QString blogIcon;
+    QString blogName;
+};
+
+} // namespace Internal
+
+MultiFeedRssModel::MultiFeedRssModel(QObject *parent) :
+    QAbstractListModel(parent),
+    m_networkAccessManager(new NetworkAccessManager),
+    m_articleCount(0)
+{
+    //m_namThread = new QThread;
+    //m_networkAccessManager->moveToThread(m_namThread);
+    connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
+            SLOT(appendFeedData(QNetworkReply*)), Qt::QueuedConnection);
+    //m_namThread->start();
+    //qDebug() << "MainThread" << QThread::currentThread();
+
+    QHash<int, QByteArray> roleNames;
+    roleNames[TitleRole] = "title";
+    roleNames[DescriptionRole] = "description";
+    roleNames[PubDateRole] = "pubDate";
+    roleNames[LinkRole] = "link";
+    roleNames[BlogNameRole] = "blogName";
+    roleNames[BlogIconRole] = "blogIcon";
+    setRoleNames(roleNames);
+}
+
+MultiFeedRssModel::~MultiFeedRssModel()
+{
+    //m_namThread->exit();
+    //delete m_namThread;
+}
+
+void MultiFeedRssModel::addFeed(const QString& feed)
+{
+    QMetaObject::invokeMethod(m_networkAccessManager, "getUrl",
+                              Qt::QueuedConnection, Q_ARG(QUrl, feed));
+}
+
+bool sortForPubDate(const Internal::RssItem& item1, const Internal::RssItem& item2)
+{
+    return item1.pubDate > item2.pubDate;
+}
+
+void MultiFeedRssModel::appendFeedData(QNetworkReply *reply)
+{
+    Internal::RssReader reader;
+    m_aggregatedFeed.append(reader.parse(reply));
+    qSort(m_aggregatedFeed.begin(), m_aggregatedFeed.end(), sortForPubDate);
+    setArticleCount(m_aggregatedFeed.size());
+    reset();
+}
+
+void MultiFeedRssModel::removeFeed(const QString &feed)
+{
+    QMutableListIterator<Internal::RssItem> it(m_aggregatedFeed);
+    while (it.hasNext()) {
+        Internal::RssItem item = it.next();
+        if (item.source == feed)
+            it.remove();
+    }
+    setArticleCount(m_aggregatedFeed.size());
+}
+
+int MultiFeedRssModel::rowCount(const QModelIndex &) const
+{
+    return m_aggregatedFeed.size();
+}
+
+QVariant MultiFeedRssModel::data(const QModelIndex &index, int role) const
+{
+
+    Internal::RssItem item = m_aggregatedFeed.at(index.row());
+
+    switch (role) {
+    case Qt::DisplayRole: // fall through
+    case TitleRole:
+        return item.title;
+    case DescriptionRole:
+        return item.description;
+    case PubDateRole:
+        return item.pubDate;
+    case LinkRole:
+        return item.link;
+    case BlogNameRole:
+        return item.blogName;
+    case BlogIconRole:
+        return item.blogIcon;
+    }
+
+    return QVariant();
+}
+
+} // namespace Utils
diff --git a/src/plugins/coreplugin/multifeedrssmodel.h b/src/plugins/coreplugin/multifeedrssmodel.h
new file mode 100644 (file)
index 0000000..1d0d036
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef MULTIFEEDRSSMODEL_H
+#define MULTIFEEDRSSMODEL_H
+
+#include "core_global.h"
+
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QStringList>
+#include <QtCore/QDateTime>
+
+QT_BEGIN_NAMESPACE
+class QThread;
+class QNetworkReply;
+QT_END_NAMESPACE
+
+namespace Core {
+
+namespace Internal {
+
+struct RssItem {
+    QString source;
+    QString title;
+    QString link;
+    QString description;
+    QString blogName;
+    QString blogIcon;
+    QDateTime pubDate;
+
+};
+typedef QList<RssItem> RssItemList;
+
+} // namespace Internal
+
+class NetworkAccessManager;
+
+enum RssRoles { TitleRole = Qt::UserRole+1, DescriptionRole, LinkRole,
+                PubDateRole, BlogNameRole, BlogIconRole };
+
+class CORE_EXPORT MultiFeedRssModel : public QAbstractListModel {
+    Q_OBJECT
+    Q_PROPERTY(int articleCount READ articleCount WRITE setArticleCount NOTIFY articleCountChanged)
+public:
+    explicit MultiFeedRssModel(QObject *parent);
+    ~MultiFeedRssModel();
+    void addFeed(const QString& feed);
+    void removeFeed(const QString& feed);
+
+    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+    int articleCount() const { return m_articleCount; }
+
+public slots:
+    void setArticleCount(int arg)
+    {
+        if (m_articleCount != arg) {
+            m_articleCount = arg;
+            emit articleCountChanged(arg);
+        }
+    }
+
+signals:
+    void articleCountChanged(int arg);
+
+private slots:
+    void appendFeedData(QNetworkReply *reply);
+
+private:
+    QStringList m_sites;
+    Internal::RssItemList m_aggregatedFeed;
+    NetworkAccessManager *m_networkAccessManager;
+    QThread *m_namThread;
+    int m_articleCount;
+};
+
+} // namespace Utils
+
+#endif // MULTIFEEDRSSMODEL_H
+
+
diff --git a/src/plugins/coreplugin/networkaccessmanager.cpp b/src/plugins/coreplugin/networkaccessmanager.cpp
new file mode 100644 (file)
index 0000000..8297e94
--- /dev/null
@@ -0,0 +1,113 @@
+#include "networkaccessmanager.h"
+
+#include <QtCore/QLocale>
+#include <QtNetwork/QNetworkReply>
+
+#ifdef Q_OS_UNIX
+#include <sys/utsname.h>
+#endif
+
+#include "coreconstants.h"
+
+/*!
+   \class Core::NetworkManager
+
+   \brief Network Access Manager for use with Qt Creator.
+
+   Common initialization, Qt Creator User Agent
+ */
+
+namespace Core {
+
+static const QString getOsString()
+{
+    QString osString;
+#if defined(Q_OS_WIN)
+    switch (QSysInfo::WindowsVersion) {
+    case (QSysInfo::WV_4_0):
+        osString += QLatin1String("WinNT4.0");
+        break;
+    case (QSysInfo::WV_5_0):
+        osString += QLatin1String("Windows NT 5.0");
+        break;
+    case (QSysInfo::WV_5_1):
+        osString += QLatin1String("Windows NT 5.1");
+        break;
+    case (QSysInfo::WV_5_2):
+        osString += QLatin1String("Windows NT 5.2");
+        break;
+    case (QSysInfo::WV_6_0):
+        osString += QLatin1String("Windows NT 6.0");
+        break;
+    case (QSysInfo::WV_6_1):
+        osString += QLatin1String("Windows NT 6.1");
+        break;
+    default:
+        osString += QLatin1String("Windows NT (Unknown)");
+        break;
+    }
+#elif defined (Q_OS_MAC)
+    if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
+        osString += QLatin1String("PPC ");
+    else
+        osString += QLatin1String("Intel ");
+    osString += QLatin1String("Mac OS X ");
+    switch (QSysInfo::MacintoshVersion) {
+    case (QSysInfo::MV_10_3):
+        osString += QLatin1String("10_3");
+        break;
+    case (QSysInfo::MV_10_4):
+        osString += QLatin1String("10_4");
+        break;
+    case (QSysInfo::MV_10_5):
+        osString += QLatin1String("10_5");
+        break;
+    case (QSysInfo::MV_10_6):
+        osString += QLatin1String("10_6");
+        break;
+    default:
+        osString += QLatin1String("(Unknown)");
+        break;
+    }
+#elif defined (Q_OS_UNIX)
+    struct utsname uts;
+    if (uname(&uts) == 0) {
+        osString += QLatin1String(uts.sysname);
+        osString += QLatin1Char(' ');
+        osString += QLatin1String(uts.release);
+    } else {
+        osString += QLatin1String("Unix (Unknown)");
+    }
+#else
+    ossttring = QLatin1String("Unknown OS");
+#endif
+    return osString;
+}
+
+
+NetworkAccessManager::NetworkAccessManager(QObject *parent)
+    : QNetworkAccessManager(parent)
+{
+
+}
+
+void NetworkAccessManager::getUrl(const QUrl &url)
+{
+    QNetworkRequest req;
+    req.setUrl(url);
+    get(req);
+}
+
+QNetworkReply* NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
+{
+    QString agentStr = QString::fromLatin1("Qt-Creator/%1 (QNetworkAccessManager %2; %3; %4; %5 bit)")
+                    .arg(Core::Constants::IDE_VERSION_LONG).arg(qVersion())
+                    .arg(getOsString()).arg(QLocale::system().name())
+                    .arg(QSysInfo::WordSize);
+    QNetworkRequest req(request);
+    req.setRawHeader("User-Agent", agentStr.toLatin1());
+    return QNetworkAccessManager::createRequest(op, req, outgoingData);
+}
+
+
+} // namespace utils
diff --git a/src/plugins/coreplugin/networkaccessmanager.h b/src/plugins/coreplugin/networkaccessmanager.h
new file mode 100644 (file)
index 0000000..cd4a8aa
--- /dev/null
@@ -0,0 +1,22 @@
+#include "core_global.h"
+
+#include <QtCore/QUrl>
+#include <QtNetwork/QNetworkAccessManager>
+
+namespace Core {
+
+class CORE_EXPORT NetworkAccessManager : public QNetworkAccessManager
+{
+    Q_OBJECT
+public:
+    NetworkAccessManager(QObject *parent = 0);
+
+public slots:
+    void getUrl(const QUrl &url);
+
+protected:
+    virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData);
+};
+
+
+} // namespace utils
index 95142e8..17deae1 100644 (file)
@@ -34,9 +34,9 @@
 #include <cpptools/cpptoolsconstants.h>
 #include <qmljseditor/qmljseditorconstants.h>
 #include <coreplugin/icore.h>
+#include <coreplugin/networkaccessmanager.h>
 #include <coreplugin/dialogs/ioptionspage.h>
 
-#include <QtNetwork/QNetworkAccessManager>
 #include <QtNetwork/QNetworkRequest>
 #include <QtNetwork/QNetworkReply>
 
@@ -193,7 +193,7 @@ QNetworkReply *NetworkAccessManagerProxy::httpPost(const QString &link, const QB
 QNetworkAccessManager *NetworkAccessManagerProxy::networkAccessManager()
 {
     if (m_networkAccessManager.isNull())
-        m_networkAccessManager.reset(new QNetworkAccessManager);
+        m_networkAccessManager.reset(new Core::NetworkAccessManager);
     return m_networkAccessManager.data();
 }
 
index 19324de..1a3cdee 100644 (file)
 #include <QtCore/QXmlStreamReader>
 #include <QtCore/QSettings>
 
-#include <QtNetwork/QNetworkAccessManager>
 #include <QtNetwork/QNetworkReply>
 
+#include <coreplugin/networkaccessmanager.h>
+
 enum { debug = 0 };
 
 enum Protocol { ListCategoriesProtocol, ListProjectsProtocol };
@@ -528,7 +529,7 @@ void Gitorious::slotReplyFinished()
 QNetworkReply *Gitorious::createRequest(const QUrl &url, int protocol, int hostIndex, int page)
 {
     if (!m_networkManager)
-        m_networkManager = new QNetworkAccessManager(this);
+        m_networkManager = new Core::NetworkAccessManager(this);
     QNetworkReply *reply = m_networkManager->get(QNetworkRequest(url));
     connect(reply, SIGNAL(finished()), this, SLOT(slotReplyFinished()));
     reply->setProperty(protocolPropertyC, QVariant(protocol));
index 611ac2a..5ae3576 100644 (file)
@@ -256,6 +256,19 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error)
     am->actionContainer(M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
 #endif
 
+    action = new QAction(tr("Technical Support"), this);
+    cmd = am->registerAction(action, Core::Id("Help.TechSupport"), globalcontext);
+    am->actionContainer(M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
+    connect(action, SIGNAL(triggered()), this, SLOT(slotOpenSupportPage()));
+
+#ifndef Q_WS_MAC
+    action = new QAction(this);
+    action->setSeparator(true);
+    cmd = am->registerAction(action, Core::Id("Help.Separator2"), globalcontext);
+    am->actionContainer(M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
+    connect(action, SIGNAL(triggered()), this, SLOT(activateContext()));
+#endif
+
     action = new QAction(this);
     am->registerAction(action, Core::Constants::PRINT, modecontext);
     connect(action, SIGNAL(triggered()), m_centralWidget, SLOT(print()));
@@ -1121,7 +1134,7 @@ void HelpPlugin::handleHelpRequest(const QUrl &url)
         if (address.startsWith(HelpViewer::NsNokia)
             || address.startsWith(HelpViewer::NsTrolltech)) {
                 // local help not installed, resort to external web help
-                QString urlPrefix = QLatin1String("http://doc.trolltech.com/");
+                QString urlPrefix = QLatin1String("http://doc.qt.nokia.com/");
                 if (url.authority() == QLatin1String("com.nokia.qtcreator")) {
                     urlPrefix.append(QString::fromLatin1("qtcreator"));
                 } else {
@@ -1192,6 +1205,11 @@ void HelpPlugin::slotOpenActionUrl(QAction *action)
 #endif
 }
 
+void HelpPlugin::slotOpenSupportPage()
+{
+    switchToHelpMode(QUrl("qthelp://com.nokia.qtcreator/doc/technical-support.html"));
+}
+
 void HelpPlugin::openFindToolBar()
 {
     if (Find::FindPlugin::instance())
index 6b6d2b4..2700cd6 100644 (file)
@@ -115,6 +115,7 @@ private slots:
     void slotAboutToShowBackMenu();
     void slotAboutToShowNextMenu();
     void slotOpenActionUrl(QAction *action);
+    void slotOpenSupportPage();
 
     void openFindToolBar();
 
index 450f9a2..d749374 100644 (file)
 
 #include <QtHelp/QHelpEngine>
 
-#include <QtNetwork/QNetworkAccessManager>
 #include <QtNetwork/QNetworkReply>
 #include <QtNetwork/QNetworkRequest>
 
+#include <coreplugin/networkaccessmanager.h>
+
 using namespace Find;
 using namespace Help;
 using namespace Help::Internal;
@@ -106,7 +107,7 @@ qint64 HelpNetworkReply::readData(char *buffer, qint64 maxlen)
 
 // -- HelpNetworkAccessManager
 
-class HelpNetworkAccessManager : public QNetworkAccessManager
+class HelpNetworkAccessManager : public Core::NetworkAccessManager
 {
 public:
     HelpNetworkAccessManager(QObject *parent);
@@ -117,7 +118,7 @@ protected:
 };
 
 HelpNetworkAccessManager::HelpNetworkAccessManager(QObject *parent)
-    : QNetworkAccessManager(parent)
+    : Core::NetworkAccessManager(parent)
 {
 }
 
@@ -125,7 +126,7 @@ QNetworkReply *HelpNetworkAccessManager::createRequest(Operation op,
     const QNetworkRequest &request, QIODevice* outgoingData)
 {
     if (!HelpViewer::isLocalUrl(request.url()))
-        return QNetworkAccessManager::createRequest(op, request, outgoingData);
+        return Core::NetworkAccessManager::createRequest(op, request, outgoingData);
 
     QString url = request.url().toString();
     const QHelpEngineCore &engine = LocalHelpManager::helpEngine();
index d3c7b06..8ef73ff 100644 (file)
@@ -84,6 +84,7 @@ plugin_coreplugin.subdir = coreplugin
 
 plugin_welcome.subdir = welcome
 plugin_welcome.depends = plugin_coreplugin
+plugin_welcome.depends += plugin_projectexplorer
 
 plugin_find.subdir = find
 plugin_find.depends += plugin_coreplugin
index 0e39131..315817e 100644 (file)
@@ -76,7 +76,6 @@
 #include "target.h"
 #include "projectexplorersettingspage.h"
 #include "projectwelcomepage.h"
-#include "projectwelcomepagewidget.h"
 #include "corelistenercheckingforrunningbuild.h"
 #include "buildconfiguration.h"
 #include "miniprojecttargetselector.h"
@@ -1305,7 +1304,7 @@ Project *ProjectExplorerPlugin::startupProject() const
 
 void ProjectExplorerPlugin::updateWelcomePage()
 {
-    ProjectWelcomePageWidget::WelcomePageData welcomePageData;
+    WelcomePageData welcomePageData;
     welcomePageData.sessionList =  d->m_session->sessions();
     welcomePageData.activeSession = d->m_session->activeSession();
     welcomePageData.previousSession = d->m_session->lastSession();
@@ -2202,6 +2201,7 @@ void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName, const Q
     d->m_recentProjects.prepend(qMakePair(prettyFileName, displayName));
     QFileInfo fi(prettyFileName);
     d->m_lastOpenDirectory = fi.absolutePath();
+    emit recentProjectsChanged();
 }
 
 void ProjectExplorerPlugin::updateRecentProjectMenu()
@@ -2236,6 +2236,7 @@ void ProjectExplorerPlugin::updateRecentProjectMenu()
                                           "Core", Core::Constants::TR_CLEAR_MENU));
         connect(action, SIGNAL(triggered()), this, SLOT(clearRecentProjects()));
     }
+    emit recentProjectsChanged();
 }
 
 void ProjectExplorerPlugin::clearRecentProjects()
@@ -2756,4 +2757,9 @@ void ProjectExplorerPlugin::openOpenProjectDialog()
         Core::ICore::instance()->openFiles(files, Core::ICore::SwitchMode);
 }
 
+QList<QPair<QString, QString> > ProjectExplorerPlugin::recentProjects()
+{
+    return d->m_recentProjects;
+}
+
 Q_EXPORT_PLUGIN(ProjectExplorerPlugin)
index 5885db4..f383dce 100644 (file)
@@ -33,6 +33,8 @@
 #ifndef PROJECTEXPLORER_H
 #define PROJECTEXPLORER_H
 
+#include <QtCore/QPair>
+
 #include "projectexplorer_export.h"
 
 #include <extensionsystem/iplugin.h>
@@ -116,6 +118,7 @@ public:
     void renameFile(Node *node, const QString &to);
     static QStringList projectFilePatterns();
     bool coreAboutToClose();
+    QList<QPair<QString, QString> > recentProjects();
 
     bool canRun(Project *pro, const QString &runMode);
     QString cannotRunReason(Project *project, const QString &runMode);
@@ -138,6 +141,7 @@ signals:
     void currentProjectChanged(ProjectExplorer::Project *project);
     void currentNodeChanged(ProjectExplorer::Node *node, ProjectExplorer::Project *project);
     void aboutToExecuteProject(ProjectExplorer::Project *project, const QString &runMode);
+    void recentProjectsChanged();
 
     void settingsChanged();
 
index 08f372c..2f1c57c 100644 (file)
@@ -1,6 +1,9 @@
 TEMPLATE = lib
 TARGET = ProjectExplorer
-QT += network script
+QT += xml \
+    script \
+    network \
+    declarative
 include(../../qtcreatorplugin.pri)
 include(projectexplorer_dependencies.pri)
 include(../../libs/utils/utils.pri)
@@ -78,7 +81,6 @@ HEADERS += projectexplorer.h \
     debugginghelper.h \
     projectexplorersettingspage.h \
     projectwelcomepage.h \
-    projectwelcomepagewidget.h \
     baseprojectwizarddialog.h \
     miniprojecttargetselector.h \
     targetselector.h \
@@ -169,7 +171,6 @@ SOURCES += projectexplorer.cpp \
     debugginghelper.cpp \
     projectexplorersettingspage.cpp \
     projectwelcomepage.cpp \
-    projectwelcomepagewidget.cpp \
     corelistenercheckingforrunningbuild.cpp \
     baseprojectwizarddialog.cpp \
     miniprojecttargetselector.cpp \
@@ -198,7 +199,6 @@ FORMS += processstep.ui \
     projectwizardpage.ui \
     removefiledialog.ui \
     projectexplorersettingspage.ui \
-    projectwelcomepagewidget.ui \
     targetsettingswidget.ui \
     doubletabwidget.ui \
     publishing/publishingwizardselectiondialog.ui \
index 20bb43f..e1d44c1 100644 (file)
 **************************************************************************/
 
 #include "projectwelcomepage.h"
-#include "projectwelcomepagewidget.h"
+
+#include <utils/stringutils.h>
+
+#include <QtDeclarative/QDeclarativeEngine>
+#include <QtDeclarative/QDeclarativeContext>
+
+#include <coreplugin/multifeedrssmodel.h>
+
+#include <projectexplorer/session.h>
+#include <projectexplorer/projectexplorer.h>
 
 namespace ProjectExplorer {
 namespace Internal {
 
-ProjectWelcomePage::ProjectWelcomePage()
-    : m_page(0)
+SessionModel::SessionModel(SessionManager *manager, QObject *parent)
+    : QAbstractListModel(parent), m_manager(manager)
+{
+    QHash<int, QByteArray> roleNames;
+    roleNames[Qt::DisplayRole] = "sessionName";
+    roleNames[DefaultSessionRole] = "defaultSession";
+    roleNames[CurrentSessionRole] = "currentSession";
+    setRoleNames(roleNames);
+    connect(manager, SIGNAL(sessionLoaded()), SLOT(resetSessions()));
+}
+
+int SessionModel::rowCount(const QModelIndex &) const
+{
+    return qMin(m_manager->sessions().count(), 12);
+}
+
+QVariant SessionModel::data(const QModelIndex &index, int role) const
+{
+    if (role == Qt::DisplayRole || role == DefaultSessionRole || role == CurrentSessionRole) {
+        QString sessionName = m_manager->sessions().at(index.row());
+        if (role == Qt::DisplayRole)
+            return sessionName;
+        else if (role == DefaultSessionRole)
+            return m_manager->isDefaultSession(sessionName);
+        else if (role == CurrentSessionRole)
+            return sessionName == m_manager->currentSession();
+    } else
+        return QVariant();
+}
+
+
+void SessionModel::resetSessions()
+{
+    reset();
+}
+
+
+ProjectModel::ProjectModel(ProjectExplorerPlugin *plugin, QObject *parent)
+    : QAbstractListModel(parent), m_plugin(plugin)
+{
+    QHash<int, QByteArray> roleNames;
+    roleNames[Qt::DisplayRole] = "displayName";
+    roleNames[FilePathRole] = "filePath";
+    roleNames[PrettyFilePathRole] = "prettyFilePath";
+    setRoleNames(roleNames);
+    connect(plugin, SIGNAL(recentProjectsChanged()), SLOT(resetProjects()));
+}
+
+int ProjectModel::rowCount(const QModelIndex &) const
+{
+    return qMin(m_plugin->recentProjects().count(), 6);
+}
+
+QVariant ProjectModel::data(const QModelIndex &index, int role) const
+{
+    QPair<QString,QString> data = m_plugin->recentProjects().at(index.row());
+    switch (role) {
+    case Qt::DisplayRole:
+        return data.second;
+        break;
+    case FilePathRole:
+        return data.first;
+    case PrettyFilePathRole:
+        return Utils::withTildeHomePath(data.first);
+    default:
+        return QVariant();
+    }
+
+    return QVariant();
+}
+
+void ProjectModel::resetProjects()
 {
+    reset();
 }
 
-QWidget *ProjectWelcomePage::page()
+///////////////////
+
+ProjectWelcomePage::ProjectWelcomePage()
 {
-    if (!m_page) {
-        m_page = new ProjectWelcomePageWidget;
+}
 
-        // Forward signals
-        connect(m_page, SIGNAL(requestProject(QString)), this, SIGNAL(requestProject(QString)));
-        connect(m_page, SIGNAL(requestSession(QString)), this, SIGNAL(requestSession(QString)));
-        connect(m_page, SIGNAL(manageSessions()), this, SIGNAL(manageSessions()));
+void ProjectWelcomePage::facilitateQml(QDeclarativeEngine *engine)
+{
+    static const char feedGroupName[] = "Feeds";
 
-        m_page->updateWelcomePage(m_welcomePageData);
+    QDeclarativeContext *ctx = engine->rootContext();
+    ProjectExplorerPlugin *pePlugin = ProjectExplorer::ProjectExplorerPlugin::instance();
+    ctx->setContextProperty("sessionList", new SessionModel(pePlugin->session(), this));
+    ctx->setContextProperty("projectList", new ProjectModel(pePlugin, this));
+    Core::MultiFeedRssModel *rssModel = new Core::MultiFeedRssModel(this);
+    QSettings *settings = Core::ICore::instance()->settings();
+    if (settings->childGroups().contains(feedGroupName)) {
+        int size = settings->beginReadArray(feedGroupName);
+        for (int i = 0; i < size; ++i)
+        {
+            settings->setArrayIndex(i);
+            rssModel->addFeed(settings->value("url").toString());
+        }
+        settings->endArray();
+    } else {
+        rssModel->addFeed(QLatin1String("http://labs.trolltech.com/blogs/feed"));
+        rssModel->addFeed(QLatin1String("http://feeds.feedburner.com/TheQtBlog?format=xml"));
     }
-    return m_page;
+
+    ctx->setContextProperty("aggregatedFeedsModel", rssModel);
+    ctx->setContextProperty("projectWelcomePage", this);
 }
 
-void ProjectWelcomePage::setWelcomePageData(const ProjectWelcomePageWidget::WelcomePageData &welcomePageData)
+void ProjectWelcomePage::setWelcomePageData(const WelcomePageData &welcomePageData)
 {
     m_welcomePageData = welcomePageData;
-
-    if (m_page)
-        m_page->updateWelcomePage(welcomePageData);
 }
 
 } // namespace Internal
index 7c41f0e..5b3d2da 100644 (file)
 #ifndef PROJECTWELCOMEPAGE_H
 #define PROJECTWELCOMEPAGE_H
 
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QStringList>
+
 #include <utils/iwelcomepage.h>
+#include <coreplugin/icore.h>
 
-#include "projectwelcomepagewidget.h"
+QT_BEGIN_NAMESPACE
+class QDeclarativeEngine;
+QT_END_NAMESPACE
 
 namespace ProjectExplorer {
+
+class ProjectExplorerPlugin;
+class SessionManager;
+
 namespace Internal {
 
+struct WelcomePageData {
+    bool operator==(const WelcomePageData &rhs) const;
+    bool operator!=(const WelcomePageData &rhs) const;
+
+    QString previousSession;
+    QString activeSession;
+    QStringList sessionList;
+    QList<QPair<QString, QString> > projectList; // pair of filename, displayname
+};
+
+
+class SessionModel : public QAbstractListModel
+{
+    Q_OBJECT
+public:
+    enum { DefaultSessionRole = Qt::UserRole+1, CurrentSessionRole };
+
+    SessionModel(SessionManager* manager, QObject* parent = 0);
+    int rowCount(const QModelIndex &parent) const;
+    QVariant data(const QModelIndex &index, int role) const;
+
+public slots:
+    void resetSessions();
+
+private:
+    SessionManager *m_manager;
+};
+
+
+class ProjectModel : public QAbstractListModel
+{
+    Q_OBJECT
+public:
+    enum { FilePathRole = Qt::UserRole+1, PrettyFilePathRole };
+
+    ProjectModel(ProjectExplorerPlugin* plugin, QObject* parent = 0);
+    int rowCount(const QModelIndex &parent) const;
+    QVariant data(const QModelIndex &index, int role) const;
+
+public slots:
+    void resetProjects();
+
+private:
+    ProjectExplorerPlugin *m_plugin;
+};
+
 class ProjectWelcomePage : public Utils::IWelcomePage
 {
     Q_OBJECT
 public:
     ProjectWelcomePage();
 
-    QWidget *page();
+    void facilitateQml(QDeclarativeEngine *engine);
+    QString pageLocation() const { return Core::ICore::instance()->resourcePath() + QLatin1String("/welcomescreen/develop.qml"); }
+    QWidget *page() { return 0; }
     QString title() const { return tr("Develop"); }
     int priority() const { return 20; }
 
-    void setWelcomePageData(const ProjectWelcomePageWidget::WelcomePageData &welcomePageData);
+    void setWelcomePageData(const WelcomePageData &welcomePageData);
 
 signals:
     void requestProject(const QString &project);
@@ -58,8 +116,7 @@ signals:
     void manageSessions();
 
 private:
-    ProjectWelcomePageWidget *m_page;
-    ProjectWelcomePageWidget::WelcomePageData m_welcomePageData;
+    WelcomePageData m_welcomePageData;
 };
 
 } // namespace Internal
diff --git a/src/plugins/projectexplorer/projectwelcomepagewidget.h b/src/plugins/projectexplorer/projectwelcomepagewidget.h
deleted file mode 100644 (file)
index 2b31892..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (info@qt.nokia.com)
-**
-**
-** GNU Lesser General Public License Usage
-**
-** 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.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at info@qt.nokia.com.
-**
-**************************************************************************/
-
-#ifndef PROJECTWELCOMEPAGEWIDGET_H
-#define PROJECTWELCOMEPAGEWIDGET_H
-
-#include <QtGui/QWidget>
-
-
-namespace ProjectExplorer {
-namespace Internal {
-
-
-namespace Ui {
-    class ProjectWelcomePageWidget;
-}
-
-// Documentation inside.
-class ProjectWelcomePageWidget : public QWidget
-{
-    Q_OBJECT
-public:
-    ProjectWelcomePageWidget(QWidget *parent = 0);
-    ~ProjectWelcomePageWidget();
-
-    struct WelcomePageData {
-        bool operator==(const WelcomePageData &rhs) const;
-        bool operator!=(const WelcomePageData &rhs) const;
-
-        QString previousSession;
-        QString activeSession;
-        QStringList sessionList;
-        QList<QPair<QString, QString> > projectList; // pair of filename, displayname
-    };
-
-    void updateWelcomePage(const WelcomePageData &welcomePageData);
-
-signals:
-    void requestProject(const QString &project);
-    void requestSession(const QString &session);
-    void manageSessions();
-
-private slots:
-    void slotSessionClicked(const QString &data);
-    void slotProjectClicked(const QString &data);
-    void slotCreateNewProject();
-
-private:
-    void activateEditMode();
-    Ui::ProjectWelcomePageWidget *ui;
-    WelcomePageData lastData;
-};
-
-} // namespace Internal
-} // namespace ProjectExplorer
-
-#endif // PROJECTWELCOMEPAGEWIDGET_H
diff --git a/src/plugins/projectexplorer/projectwelcomepagewidget.ui b/src/plugins/projectexplorer/projectwelcomepagewidget.ui
deleted file mode 100644 (file)
index 0692434..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ProjectExplorer::Internal::ProjectWelcomePageWidget</class>
- <widget class="QWidget" name="ProjectExplorer::Internal::ProjectWelcomePageWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>696</width>
-    <height>221</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <property name="leftMargin">
-    <number>0</number>
-   </property>
-   <property name="topMargin">
-    <number>0</number>
-   </property>
-   <property name="rightMargin">
-    <number>0</number>
-   </property>
-   <property name="bottomMargin">
-    <number>2</number>
-   </property>
-   <item>
-    <widget class="QFrame" name="contentframe">
-     <property name="frameShape">
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Raised</enum>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout">
-        <item>
-         <widget class="QFrame" name="recentProjectsFrame">
-          <layout class="QVBoxLayout" name="verticalLayout_3">
-           <item>
-            <widget class="Utils::WelcomeModeLabel" name="recentSessionsTitleLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="text">
-              <string>Recent Sessions</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="Utils::WelcomeModeTreeWidget" name="sessTreeWidget" native="true"/>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item>
-         <widget class="QFrame" name="recentSessionsFrame">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <layout class="QVBoxLayout" name="verticalLayout_4">
-           <item>
-            <widget class="Utils::WelcomeModeLabel" name="projTitleLabel">
-             <property name="text">
-              <string>Recent Projects</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="Utils::WelcomeModeTreeWidget" name="projTreeWidget" native="true"/>
-           </item>
-          </layout>
-         </widget>
-        </item>
-       </layout>
-      </item>
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_2">
-        <property name="spacing">
-         <number>6</number>
-        </property>
-        <item>
-         <widget class="QPushButton" name="manageSessionsButton">
-          <property name="minimumSize">
-           <size>
-            <width>160</width>
-            <height>36</height>
-           </size>
-          </property>
-          <property name="focusPolicy">
-           <enum>Qt::TabFocus</enum>
-          </property>
-          <property name="text">
-           <string>Manage Sessions...</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_3">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item>
-         <widget class="QPushButton" name="openProjectButton">
-          <property name="minimumSize">
-           <size>
-            <width>160</width>
-            <height>36</height>
-           </size>
-          </property>
-          <property name="text">
-           <string>Open Project...</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="createNewProjectButton">
-          <property name="minimumSize">
-           <size>
-            <width>160</width>
-            <height>36</height>
-           </size>
-          </property>
-          <property name="focusPolicy">
-           <enum>Qt::TabFocus</enum>
-          </property>
-          <property name="text">
-           <string>Create Project...</string>
-          </property>
-          <property name="flat">
-           <bool>false</bool>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </item>
-     </layout>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>Utils::WelcomeModeTreeWidget</class>
-   <extends>QWidget</extends>
-   <header location="global">utils/welcomemodetreewidget.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>Utils::WelcomeModeLabel</class>
-   <extends>QLabel</extends>
-   <header location="global">utils/welcomemodetreewidget.h</header>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/qt4projectmanager/gettingstartedwelcomepage.cpp b/src/plugins/qt4projectmanager/gettingstartedwelcomepage.cpp
deleted file mode 100644 (file)
index 86b510e..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (info@qt.nokia.com)
-**
-**
-** GNU Lesser General Public License Usage
-**
-** 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.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at info@qt.nokia.com.
-**
-**************************************************************************/
-
-#include "gettingstartedwelcomepage.h"
-#include "gettingstartedwelcomepagewidget.h"
-
-namespace Qt4ProjectManager {
-namespace Internal {
-
-GettingStartedWelcomePage::GettingStartedWelcomePage()
-    : m_page(0)
-{
-}
-
-QWidget *GettingStartedWelcomePage::page()
-{
-    if (!m_page)
-        m_page = new GettingStartedWelcomePageWidget;
-    return m_page;
-}
-
-void GettingStartedWelcomePage::updateExamples(const QString &examplePath,
-                                               const QString &demosPath,
-                                               const QString &sourcePath)
-{
-    if (m_page)
-        m_page->updateExamples(examplePath, demosPath, sourcePath);
-}
-
-} // namespace Internal
-} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui
deleted file mode 100644 (file)
index 788470b..0000000
+++ /dev/null
@@ -1,629 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Qt4ProjectManager::Internal::GettingStartedWelcomePageWidget</class>
- <widget class="QWidget" name="Qt4ProjectManager::Internal::GettingStartedWelcomePageWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>749</width>
-    <height>366</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QHBoxLayout" name="horizontalLayout_3">
-   <property name="spacing">
-    <number>0</number>
-   </property>
-   <property name="margin">
-    <number>0</number>
-   </property>
-   <item>
-    <widget class="QFrame" name="contentframe">
-     <property name="styleSheet">
-      <string notr="true"/>
-     </property>
-     <property name="frameShape">
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Raised</enum>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_2">
-      <item row="0" column="0">
-       <widget class="QFrame" name="tutorialsFrame">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <layout class="QGridLayout" name="gridLayout_6">
-         <property name="verticalSpacing">
-          <number>12</number>
-         </property>
-         <item row="0" column="0">
-          <widget class="Utils::WelcomeModeLabel" name="tutorialsTitleLabel">
-           <property name="text">
-            <string>Tutorials</string>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="0">
-          <widget class="Utils::WelcomeModeTreeWidget" name="tutorialTreeWidget" native="true">
-           <property name="minimumSize">
-            <size>
-             <width>260</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="maximumSize">
-            <size>
-             <width>260</width>
-             <height>16777215</height>
-            </size>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QFrame" name="didyouKnowFrame">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="minimumSize">
-         <size>
-          <width>240</width>
-          <height>0</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>240</width>
-          <height>16777215</height>
-         </size>
-        </property>
-        <layout class="QGridLayout" name="gridLayout_11">
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <property name="verticalSpacing">
-          <number>12</number>
-         </property>
-         <item row="0" column="0">
-          <layout class="QVBoxLayout" name="verticalLayout">
-           <item>
-            <spacer name="verticalSpacer_2">
-             <property name="orientation">
-              <enum>Qt::Vertical</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>0</width>
-               <height>0</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item>
-            <widget class="Utils::WelcomeModeLabel" name="didYouKnowTitleLabel">
-             <property name="text">
-              <string>Did You Know?</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <spacer name="verticalSpacer">
-             <property name="orientation">
-              <enum>Qt::Vertical</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>0</width>
-               <height>0</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-          </layout>
-         </item>
-         <item row="0" column="1">
-          <spacer name="horizontalSpacer_5">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item row="0" column="2">
-          <layout class="QGridLayout" name="gridLayout_10">
-           <property name="spacing">
-            <number>0</number>
-           </property>
-           <item row="0" column="0" colspan="2">
-            <spacer name="verticalSpacer_4">
-             <property name="orientation">
-              <enum>Qt::Vertical</enum>
-             </property>
-             <property name="sizeType">
-              <enum>QSizePolicy::Preferred</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>20</width>
-               <height>13</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item row="1" column="1">
-            <widget class="QToolButton" name="nextTipBtn">
-             <property name="styleSheet">
-              <string notr="true">QToolButton{
-       border-left:solid 0 px;
-       height:16px;
-       width:12px;
-}
-</string>
-             </property>
-             <property name="text">
-              <string/>
-             </property>
-             <property name="icon">
-              <iconset resource="../welcome/welcome.qrc">
-               <normaloff>:/welcome/images/arrow-right.png</normaloff>:/welcome/images/arrow-right.png</iconset>
-             </property>
-             <property name="arrowType">
-              <enum>Qt::NoArrow</enum>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0">
-            <widget class="QToolButton" name="prevTipBtn">
-             <property name="styleSheet">
-              <string notr="true">QToolButton{
-       border-right:solid 0 px;
-       height:16px;
-       width:12px;
-}
-</string>
-             </property>
-             <property name="text">
-              <string/>
-             </property>
-             <property name="icon">
-              <iconset resource="../welcome/welcome.qrc">
-               <normaloff>:/welcome/images/arrow-left.png</normaloff>:/welcome/images/arrow-left.png</iconset>
-             </property>
-             <property name="arrowType">
-              <enum>Qt::NoArrow</enum>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0" colspan="2">
-            <spacer name="verticalSpacer_3">
-             <property name="orientation">
-              <enum>Qt::Vertical</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>20</width>
-               <height>13</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-          </layout>
-         </item>
-         <item row="1" column="0" colspan="3">
-          <widget class="QTextBrowser" name="didYouKnowTextBrowser">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="frameShape">
-            <enum>QFrame::NoFrame</enum>
-           </property>
-           <property name="frameShadow">
-            <enum>QFrame::Plain</enum>
-           </property>
-           <property name="verticalScrollBarPolicy">
-            <enum>Qt::ScrollBarAlwaysOff</enum>
-           </property>
-           <property name="horizontalScrollBarPolicy">
-            <enum>Qt::ScrollBarAlwaysOff</enum>
-           </property>
-           <property name="openExternalLinks">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item row="1" column="0" colspan="2">
-       <widget class="QFrame" name="demosExamplesFrame_2">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <layout class="QGridLayout" name="gridLayout">
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <item row="0" column="0">
-          <widget class="Utils::WelcomeModeLabel" name="demoTitleLabel_4">
-           <property name="text">
-            <string>Examples</string>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="0">
-          <widget class="QLabel" name="demoTitleLabel">
-           <property name="text">
-            <string>Explore Qt C++ examples:</string>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="1">
-          <widget class="QPushButton" name="cppExamplesButton">
-           <property name="enabled">
-            <bool>false</bool>
-           </property>
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>0</width>
-             <height>30</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Examples Not Installed...</string>
-           </property>
-          </widget>
-         </item>
-         <item row="2" column="0">
-          <widget class="QLabel" name="demoTitleLabel_2">
-           <property name="text">
-            <string>Explore Qt Quick examples:</string>
-           </property>
-          </widget>
-         </item>
-         <item row="2" column="1">
-          <widget class="QPushButton" name="qmlExamplesButton">
-           <property name="enabled">
-            <bool>false</bool>
-           </property>
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>0</width>
-             <height>30</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Examples Not Installed...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item row="2" column="0" colspan="2">
-       <layout class="QHBoxLayout" name="horizontalLayout_2">
-        <property name="spacing">
-         <number>6</number>
-        </property>
-        <item>
-         <spacer name="horizontalSpacer_2">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item>
-         <widget class="QPushButton" name="openProjectButton">
-          <property name="minimumSize">
-           <size>
-            <width>160</width>
-            <height>36</height>
-           </size>
-          </property>
-          <property name="text">
-           <string>Open Project...</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="createNewProjectButton">
-          <property name="minimumSize">
-           <size>
-            <width>160</width>
-            <height>36</height>
-           </size>
-          </property>
-          <property name="focusPolicy">
-           <enum>Qt::TabFocus</enum>
-          </property>
-          <property name="text">
-           <string>Create Project...</string>
-          </property>
-          <property name="flat">
-           <bool>false</bool>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QFrame" name="featureFrame">
-     <property name="minimumSize">
-      <size>
-       <width>200</width>
-       <height>0</height>
-      </size>
-     </property>
-     <property name="maximumSize">
-      <size>
-       <width>200</width>
-       <height>16777215</height>
-      </size>
-     </property>
-     <property name="styleSheet">
-      <string notr="true">QFrame#featureFrame { 
-
-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(245, 245, 245, 255), stop:1 rgba(225,225,225, 255)); 
-
-border-left: 1px solid &quot;#C9C9C9&quot;;
-border-bottom: 1px solid &quot;#C9C9C9&quot;;
-}</string>
-     </property>
-     <property name="frameShape">
-      <enum>QFrame::NoFrame</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Plain</enum>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
-      <item>
-       <widget class="Utils::WelcomeModeLabel" name="demoTitleLabel_5">
-        <property name="text">
-         <string>Featured</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QLabel" name="featuredImage">
-        <property name="minimumSize">
-         <size>
-          <width>128</width>
-          <height>0</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>16777215</width>
-          <height>128</height>
-         </size>
-        </property>
-        <property name="text">
-         <string notr="true"/>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignCenter</set>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QLabel" name="featuredTextLabel">
-        <property name="text">
-         <string notr="true"/>
-        </property>
-        <property name="wordWrap">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <spacer name="verticalSpacer_8">
-        <property name="orientation">
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>20</width>
-          <height>6</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item>
-       <widget class="QLabel" name="detailsLabel">
-        <property name="text">
-         <string notr="true"/>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <spacer name="verticalSpacer_5">
-        <property name="orientation">
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>20</width>
-          <height>239</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item>
-       <layout class="QGridLayout" name="gridLayout_12">
-        <property name="spacing">
-         <number>0</number>
-        </property>
-        <item row="0" column="1" colspan="2">
-         <spacer name="verticalSpacer_6">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeType">
-           <enum>QSizePolicy::Preferred</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>13</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="1" column="2">
-         <widget class="QToolButton" name="nextFeatureBtn">
-          <property name="styleSheet">
-           <string notr="true">QToolButton{
-       border-left:solid 0 px;
-       height:16px;
-       width:12px;
-}
-</string>
-          </property>
-          <property name="text">
-           <string/>
-          </property>
-          <property name="icon">
-           <iconset resource="../welcome/welcome.qrc">
-            <normaloff>:/welcome/images/arrow-right.png</normaloff>:/welcome/images/arrow-right.png</iconset>
-          </property>
-          <property name="arrowType">
-           <enum>Qt::NoArrow</enum>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="1">
-         <widget class="QToolButton" name="prevFeatureBtn">
-          <property name="styleSheet">
-           <string notr="true">QToolButton{
-       border-right:solid 0 px;
-       height:16px;
-       width:12px;
-}
-</string>
-          </property>
-          <property name="text">
-           <string/>
-          </property>
-          <property name="icon">
-           <iconset resource="../welcome/welcome.qrc">
-            <normaloff>:/welcome/images/arrow-left.png</normaloff>:/welcome/images/arrow-left.png</iconset>
-          </property>
-          <property name="arrowType">
-           <enum>Qt::NoArrow</enum>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="1" colspan="2">
-         <spacer name="verticalSpacer_7">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>13</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="1" column="3">
-         <spacer name="horizontalSpacer">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="1" column="0">
-         <spacer name="horizontalSpacer_4">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </item>
-     </layout>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>Utils::WelcomeModeTreeWidget</class>
-   <extends>QWidget</extends>
-   <header location="global">utils/welcomemodetreewidget.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>Utils::WelcomeModeLabel</class>
-   <extends>QLabel</extends>
-   <header location="global">utils/welcomemodetreewidget.h</header>
-  </customwidget>
- </customwidgets>
- <resources>
-  <include location="../welcome/welcome.qrc"/>
- </resources>
- <connections/>
-</ui>
index 083fa29..b686b3e 100644 (file)
@@ -53,8 +53,6 @@ HEADERS += \
     projectloadwizard.h \
     qtuicodemodelsupport.h \
     externaleditors.h \
-    gettingstartedwelcomepagewidget.h \
-    gettingstartedwelcomepage.h \
     qt4buildconfiguration.h \
     qt4target.h \
     qmakeparser.h \
@@ -116,8 +114,6 @@ SOURCES += qt4projectmanagerplugin.cpp \
     projectloadwizard.cpp \
     qtuicodemodelsupport.cpp \
     externaleditors.cpp \
-    gettingstartedwelcomepagewidget.cpp \
-    gettingstartedwelcomepage.cpp \
     qt4buildconfiguration.cpp \
     qt4target.cpp \
     qmakeparser.cpp \
@@ -132,9 +128,9 @@ SOURCES += qt4projectmanagerplugin.cpp \
 FORMS += makestep.ui \
     qmakestep.ui \
     qt4projectconfigwidget.ui \
-    gettingstartedwelcomepagewidget.ui \
     showbuildlog.ui \
     librarydetailswidget.ui \
+    showbuildlog.ui \
     wizards/testwizardpage.ui \
     wizards/targetsetuppage.ui \
     wizards/qtquickappwizardsourcespage.ui \
index 83ea47b..7df4512 100644 (file)
@@ -50,7 +50,6 @@
 #include "qt4project.h"
 #include "profileeditor.h"
 #include "externaleditors.h"
-#include "gettingstartedwelcomepage.h"
 #include "profilecompletionassist.h"
 
 #include "qt-s60/s60manager.h"
@@ -99,8 +98,6 @@ Qt4ProjectManagerPlugin::~Qt4ProjectManagerPlugin()
     delete m_proFileEditorFactory;
     removeObject(m_qt4ProjectManager);
     delete m_qt4ProjectManager;
-    removeObject(m_welcomePage);
-    delete m_welcomePage;
 }
 
 bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
@@ -116,12 +113,6 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *
     m_projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
     Core::ActionManager *am = core->actionManager();
 
-
-    m_welcomePage = new GettingStartedWelcomePage;
-    addObject(m_welcomePage);
-    connect(QtSupport::QtVersionManager::instance(), SIGNAL(updateExamples(QString,QString,QString)),
-            m_welcomePage, SLOT(updateExamples(QString,QString,QString)));
-
     //create and register objects
     m_qt4ProjectManager = new Qt4Manager(this);
     addObject(m_qt4ProjectManager);
index af634fc..c6c66d3 100644 (file)
@@ -53,7 +53,6 @@ class QtVersionManager;
 namespace Internal {
 
 class ProFileEditorFactory;
-class GettingStartedWelcomePage;
 
 class Qt4ProjectManagerPlugin : public ExtensionSystem::IPlugin
 {
@@ -96,7 +95,6 @@ private:
     QAction *m_cleanSubProjectContextMenu;
     QAction *m_addLibraryAction;
     QAction *m_addLibraryActionContextMenu;
-    GettingStartedWelcomePage *m_welcomePage;
     Core::Context m_projectContext;
 };
 
diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp
new file mode 100644 (file)
index 0000000..cedb825
--- /dev/null
@@ -0,0 +1,346 @@
+#include "exampleslistmodel.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtCore/QXmlStreamReader>
+
+#include <QDebug>
+
+#include <coreplugin/icore.h>
+#include <qtsupport/qtversionmanager.h>
+
+#include <algorithm>
+
+using QtSupport::QtVersionManager;
+using QtSupport::BaseQtVersion;
+
+namespace QtSupport {
+
+namespace Internal {
+
+ExamplesListModel::ExamplesListModel(QObject *parent) :
+    QAbstractListModel(parent)
+{
+    QHash<int, QByteArray> roleNames;
+    roleNames[Name] = "name";
+    roleNames[ProjectPath] = "projectPath";
+    roleNames[ImageUrl] = "imageUrl";
+    roleNames[Description] = "description";
+    roleNames[DocUrl] = "docUrl";
+    roleNames[FilesToOpen] = "filesToOpen";
+    roleNames[Tags] = "tags";
+    roleNames[Difficulty] = "difficulty";
+    roleNames[Type] = "type";
+    roleNames[HasSourceCode] = "hasSourceCode";
+    setRoleNames(roleNames);
+
+    connect(QtVersionManager::instance(), SIGNAL(updateExamples(QString,QString,QString)),
+            SLOT(readNewsItems(QString,QString,QString)));
+}
+
+QList<ExampleItem> ExamplesListModel::parseExamples(QXmlStreamReader* reader, const QString& projectsOffset)
+{
+    QList<ExampleItem> examples;
+    ExampleItem item;
+    while (!reader->atEnd()) {
+        switch (reader->readNext()) {
+        case QXmlStreamReader::StartElement:
+            if (reader->name() == QLatin1String("example")) {
+                item = ExampleItem();
+                item.type = Example;
+                QXmlStreamAttributes attributes = reader->attributes();
+                item.name = attributes.value(QLatin1String("name")).toString();
+                item.projectPath = attributes.value(QLatin1String("projectPath")).toString();
+                item.hasSourceCode = !item.projectPath.isEmpty();
+                item.projectPath.prepend('/');
+                item.projectPath.prepend(projectsOffset);
+                item.imageUrl = attributes.value(QLatin1String("imagePath")).toString();
+                item.docUrl = attributes.value(QLatin1String("docUrl")).toString();
+            } else if (reader->name() == QLatin1String("fileToOpen")) {
+                item.filesToOpen.append(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
+            } else if (reader->name() == QLatin1String("description")) {
+                item.description =  reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement);
+            } else if (reader->name() == QLatin1String("tags")) {
+                item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(",");
+                m_tags.append(item.tags);
+            }
+            break;
+        case QXmlStreamReader::EndElement:
+            if (reader->name() == QLatin1String("example"))
+                examples.append(item);
+            else if (reader->name() == QLatin1String("examples"))
+                return examples;
+            break;
+        default: // nothing
+            break;
+        }
+    }
+    return examples;
+}
+
+QList<ExampleItem> ExamplesListModel::parseDemos(QXmlStreamReader* reader, const QString& projectsOffset)
+{
+    QList<ExampleItem> demos;
+    ExampleItem item;
+    while (!reader->atEnd()) {
+        switch (reader->readNext()) {
+        case QXmlStreamReader::StartElement:
+            if (reader->name() == QLatin1String("demo")) {
+                item = ExampleItem();
+                item.type = Demo;
+                QXmlStreamAttributes attributes = reader->attributes();
+                item.name = attributes.value(QLatin1String("name")).toString();
+                item.projectPath = attributes.value(QLatin1String("projectPath")).toString();
+                item.hasSourceCode = !item.projectPath.isEmpty();
+                item.projectPath.prepend('/');
+                item.projectPath.prepend(projectsOffset);
+                item.imageUrl = attributes.value(QLatin1String("imageUrl")).toString();
+                item.docUrl = attributes.value(QLatin1String("docUrl")).toString();
+            } else if (reader->name() == QLatin1String("fileToOpen")) {
+                item.filesToOpen.append(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
+            } else if (reader->name() == QLatin1String("description")) {
+                item.description =  reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement);
+            } else if (reader->name() == QLatin1String("tags")) {
+                item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(",");
+            }
+            break;
+        case QXmlStreamReader::EndElement:
+            if (reader->name() == QLatin1String("demo"))
+                demos.append(item);
+            else if (reader->name() == QLatin1String("demos"))
+                return demos;
+            break;
+        default: // nothing
+            break;
+        }
+    }
+    return demos;
+}
+
+QList<ExampleItem> ExamplesListModel::parseTutorials(QXmlStreamReader* reader, const QString& projectsOffset)
+{
+    QList<ExampleItem> tutorials;
+    ExampleItem item;
+    while (!reader->atEnd()) {
+        switch (reader->readNext()) {
+        case QXmlStreamReader::StartElement:
+            if (reader->name() == QLatin1String("tutorial")) {
+                item = ExampleItem();
+                item.type = Tutorial;
+                QXmlStreamAttributes attributes = reader->attributes();
+                item.name = attributes.value(QLatin1String("name")).toString();
+                item.projectPath = attributes.value(QLatin1String("projectPath")).toString();
+                item.hasSourceCode = !item.projectPath.isEmpty();
+                item.projectPath.prepend('/');
+                item.projectPath.prepend(projectsOffset);
+                item.imageUrl = attributes.value(QLatin1String("imageUrl")).toString();
+                item.docUrl = attributes.value(QLatin1String("docUrl")).toString();
+            } else if (reader->name() == QLatin1String("fileToOpen")) {
+                item.filesToOpen.append(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
+            } else if (reader->name() == QLatin1String("description")) {
+                item.description =  reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement);
+            } else if (reader->name() == QLatin1String("tags")) {
+                item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(",");
+            }
+            break;
+        case QXmlStreamReader::EndElement:
+            if (reader->name() == QLatin1String("tutorial"))
+                tutorials.append(item);
+            else if (reader->name() == QLatin1String("tutorials"))
+                return tutorials;
+            break;
+        default: // nothing
+            break;
+        }
+    }
+
+    return tutorials;
+}
+
+void ExamplesListModel::readNewsItems(const QString &examplesPath, const QString &demosPath, const QString &sourcePath)
+{
+    clear();
+    foreach (const QString exampleSource, exampleSources()) {
+        QFile exampleFile(exampleSource);
+        if (!exampleFile.open(QIODevice::ReadOnly)) {
+            qDebug() << Q_FUNC_INFO << "Could not open file" << exampleSource;
+            return;
+        }
+
+        QFileInfo fi(exampleSource);
+        QString offsetPath = fi.path();
+        QDir examplesDir(offsetPath);
+        QDir demosDir(offsetPath);
+        if (offsetPath.startsWith(Core::ICore::instance()->resourcePath())) {
+            // Try to get dir from first Qt Version
+            examplesDir = examplesPath;
+            demosDir = demosPath;
+        }
+
+        QXmlStreamReader reader(&exampleFile);
+        while (!reader.atEnd())
+            switch (reader.readNext()) {
+            case QXmlStreamReader::StartElement:
+                if (reader.name() == QLatin1String("examples"))
+                    addItems(parseExamples(&reader, examplesDir.path()));
+                else if (reader.name() == QLatin1String("demos"))
+                    addItems(parseDemos(&reader, demosDir.path()));
+                else if (reader.name() == QLatin1String("tutorials"))
+                    addItems(parseTutorials(&reader, examplesDir.path()));
+                break;
+            default: // nothing
+                break;
+            }
+
+        if (reader.hasError())
+            qDebug() << "error parsing file" <<  exampleSource << "as XML document";
+    }
+
+    m_tags.sort();
+    m_tags.erase(std::unique(m_tags.begin(), m_tags.end()), m_tags.end());
+    emit tagsUpdated();
+}
+
+QStringList ExamplesListModel::exampleSources() const
+{
+    QFileInfoList sources;
+    const QStringList pattern(QLatin1String("*.xml"));
+
+    // TODO: Read key from settings
+
+    if (sources.isEmpty()) {
+        // Try to get dir from first Qt Version
+        QtVersionManager *versionManager = QtVersionManager::instance();
+        foreach (BaseQtVersion *version, versionManager->validVersions()) {
+
+            QDir examplesDir(version->examplesPath());
+            if (examplesDir.exists())
+                sources << examplesDir.entryInfoList(pattern);
+
+            QDir demosDir(version->demosPath());
+            if (demosDir.exists())
+                sources << demosDir.entryInfoList(pattern);
+
+            if (!sources.isEmpty())
+                break;
+        }
+    }
+
+    QString resourceDir = Core::ICore::instance()->resourcePath() + QLatin1String("/welcomescreen/");
+
+    // Try Creator-provided XML file only
+    if (sources.isEmpty()) {
+        qDebug() << Q_FUNC_INFO << "falling through to Creator-provided XML file";
+        sources << QString(resourceDir + QLatin1String("/examples_fallback.xml"));
+    }
+
+    sources <<  QString(resourceDir + QLatin1String("/qtcreator_tutorials.xml"));
+
+    QStringList ret;
+    foreach (const QFileInfo& source, sources)
+        ret.append(source.filePath());
+
+    return ret;
+}
+
+void ExamplesListModel::clear()
+{
+    if (exampleItems.count() > 0) {
+        beginRemoveRows(QModelIndex(), 0,  exampleItems.size()-1);
+        exampleItems.clear();
+        endRemoveRows();
+    }
+    m_tags.clear();
+}
+
+void ExamplesListModel::addItems(const QList<ExampleItem> &newItems)
+{
+    beginInsertRows(QModelIndex(), exampleItems.size(), exampleItems.size() - 1 + newItems.size());
+    exampleItems.append(newItems);
+    endInsertRows();
+}
+
+int ExamplesListModel::rowCount(const QModelIndex &) const
+{
+    return exampleItems.size();
+}
+
+QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
+{
+
+    if (!index.isValid() || index.row()+1 > exampleItems.count()) {
+        qDebug() << Q_FUNC_INFO << "invalid index requested";
+        return QVariant();
+    }
+
+    ExampleItem item = exampleItems.at(index.row());
+    switch (role)
+    {
+    case Qt::DisplayRole: // for search only
+        return QString(item.name + ' ' + item.tags.join(" "));
+    case Name:
+        return item.name;
+    case ProjectPath:
+        return item.projectPath;
+    case Description:
+        return item.description;
+    case ImageUrl:
+        return item.imageUrl;
+    case DocUrl:
+        return item.docUrl;
+    case FilesToOpen:
+        return item.filesToOpen;
+    case Tags:
+        return item.tags;
+    case Difficulty:
+        return item.difficulty;
+    case HasSourceCode:
+        return item.hasSourceCode;
+    case Type:
+        return item.type;
+    default:
+        qDebug() << Q_FUNC_INFO << "role type not supported";
+        return QVariant();
+    }
+
+}
+
+ExamplesListModelFilter::ExamplesListModelFilter(QObject *parent) :
+    QSortFilterProxyModel(parent), m_showTutorialsOnly(true)
+{
+    connect(this, SIGNAL(showTutorialsOnlyChanged()), SLOT(updateFilter()));
+}
+
+void ExamplesListModelFilter::updateFilter()
+{
+    invalidateFilter();
+}
+
+bool ExamplesListModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+    if (m_showTutorialsOnly) {
+        int type = sourceModel()->index(sourceRow, 0, sourceParent).data(Type).toInt();
+        if (type != Tutorial)
+            return false;
+        // tag search only active if we are not in tutorial only mode
+    } else if (!m_filterTag.isEmpty()) {
+        QStringList tags = sourceModel()->index(sourceRow, 0, sourceParent).data(Tags).toStringList();
+        if (!tags.contains(m_filterTag, Qt::CaseInsensitive))
+            return false;
+    }
+
+    bool ok = QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
+    if (!ok)
+        return false;
+
+    return true;
+}
+
+void ExamplesListModelFilter::setShowTutorialsOnly(bool showTutorialsOnly)
+{
+    m_showTutorialsOnly = showTutorialsOnly;
+    emit showTutorialsOnlyChanged();
+}
+
+} // namespace Internal
+} // namespace QtSupport
diff --git a/src/plugins/qtsupport/exampleslistmodel.h b/src/plugins/qtsupport/exampleslistmodel.h
new file mode 100644 (file)
index 0000000..9781176
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef EXAMPLESLISTMODEL_H
+#define EXAMPLESLISTMODEL_H
+
+#include <QAbstractListModel>
+#include <QStringList>
+#include <QtGui/QSortFilterProxyModel>
+
+
+QT_BEGIN_NAMESPACE
+class QXmlStreamReader;
+QT_END_NAMESPACE
+
+namespace QtSupport {
+namespace Internal {
+
+enum ExampleRoles { Name=Qt::UserRole, ProjectPath, Description, ImageUrl,
+                    DocUrl,  FilesToOpen, Tags, Difficulty, HasSourceCode, Type };
+
+enum InstructionalType { Example=0, Demo, Tutorial };
+
+struct ExampleItem {
+    ExampleItem(): difficulty(0) {}
+    InstructionalType type;
+    QString name;
+    QString projectPath;
+    QString description;
+    QString imageUrl;
+    QString docUrl;
+    QStringList filesToOpen;
+    QStringList tags;
+    int difficulty;
+    bool hasSourceCode;
+};
+
+class ExamplesListModel : public QAbstractListModel {
+    Q_OBJECT
+public:
+    explicit ExamplesListModel(QObject *parent);
+    void addItems(const QList<ExampleItem> &items);
+
+    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+    QStringList tags() const { return m_tags; }
+
+public slots:
+    void readNewsItems(const QString &examplesPath, const QString &demosPath, const QString &sourcePath);
+
+signals:
+    void tagsUpdated();
+
+private:
+    QList<ExampleItem> parseExamples(QXmlStreamReader* reader, const QString& projectsOffset);
+    QList<ExampleItem> parseDemos(QXmlStreamReader* reader, const QString& projectsOffset);
+    QList<ExampleItem> parseTutorials(QXmlStreamReader* reader, const QString& projectsOffset);
+    void clear();
+    QStringList exampleSources() const;
+    QList<ExampleItem> exampleItems;
+    QStringList m_tags;
+};
+
+class ExamplesListModelFilter : public QSortFilterProxyModel {
+    Q_OBJECT
+public:
+    Q_PROPERTY(bool showTutorialsOnly READ showTutorialsOnly WRITE setShowTutorialsOnly NOTIFY showTutorialsOnlyChanged)
+    Q_PROPERTY(QString filterTag READ filterTag WRITE setFilterTag NOTIFY filterTagChanged)
+
+    explicit ExamplesListModelFilter(QObject *parent);
+
+    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+    bool showTutorialsOnly() {return m_showTutorialsOnly;}
+
+    QString filterTag() const
+    {
+        return m_filterTag;
+    }
+
+public slots:
+    void setFilterTag(const QString& arg)
+    {
+        if (m_filterTag != arg) {
+            m_filterTag = arg;
+            emit filterTagChanged(arg);
+        }
+    }
+    void updateFilter();
+
+signals:
+    void showTutorialsOnlyChanged();
+
+    void filterTagChanged(const QString& arg);
+
+private slots:
+    void setShowTutorialsOnly(bool showTutorialsOnly);
+
+private:
+    bool m_showTutorialsOnly;
+    QString m_filterTag;
+};
+
+} // namespace Internal
+} // namespace QtSupport
+
+#endif // EXAMPLESLISTMODEL_H
+
+
diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
new file mode 100644 (file)
index 0000000..37f9124
--- /dev/null
@@ -0,0 +1,124 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "gettingstartedwelcomepage.h"
+
+#include "exampleslistmodel.h"
+
+#include <coreplugin/coreplugin.h>
+#include <coreplugin/helpmanager.h>
+#include <projectexplorer/projectexplorer.h>
+
+#include <QtGui/QGraphicsProxyWidget>
+#include <QtGui/QScrollBar>
+#include <QtGui/QSortFilterProxyModel>
+#include <QtSql/QSqlQueryModel>
+#include <QtSql/QSqlQuery>
+#include <QtDeclarative>
+#include <QDebug>
+
+namespace QtSupport {
+namespace Internal {
+
+class HelpImageProvider : public QDeclarativeImageProvider
+{
+public:
+    HelpImageProvider()
+        : QDeclarativeImageProvider(QDeclarativeImageProvider::Image)
+    {
+    }
+
+    QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
+    {
+        QUrl url = QUrl::fromEncoded(id.toAscii());
+        QByteArray imgData = Core::HelpManager::instance()->fileData(url);
+        QBuffer imgBuffer(&imgData);
+        imgBuffer.open(QIODevice::ReadOnly);
+        QImageReader reader(&imgBuffer);
+        QImage img = reader.read();
+        if (size && requestedSize != *size)
+            img = img.scaled(requestedSize);
+        return img;
+    }
+};
+
+GettingStartedWelcomePage::GettingStartedWelcomePage()
+    : m_examplesModel(0), m_engine(0)
+{
+}
+
+void GettingStartedWelcomePage::facilitateQml(QDeclarativeEngine *engine)
+{
+    m_engine = engine;
+    m_engine->addImageProvider("helpimage", new HelpImageProvider);
+    m_examplesModel = new ExamplesListModel(this);
+    connect (m_examplesModel, SIGNAL(tagsUpdated()), SLOT(updateTagsModel()));
+    ExamplesListModelFilter *proxy = new ExamplesListModelFilter(this);
+    proxy->setSourceModel(m_examplesModel);
+    proxy->setDynamicSortFilter(true);
+    proxy->sort(0);
+    proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
+    QDeclarativeContext *rootContenxt = m_engine->rootContext();
+    rootContenxt->setContextProperty("examplesModel", proxy);
+    rootContenxt->setContextProperty("gettingStarted", this);
+}
+
+void GettingStartedWelcomePage::openSplitHelp(const QUrl &help)
+{
+    Core::ICore::instance()->helpManager()->handleHelpRequest(help.toString()+QLatin1String("?view=split"));
+}
+
+QStringList GettingStartedWelcomePage::tagList() const
+{
+    return m_examplesModel->tags();
+}
+
+void GettingStartedWelcomePage::openProject(const QString &projectFile, const QStringList &additionalFilesToOpen, const QUrl &help)
+{
+    qDebug() << projectFile << additionalFilesToOpen << help;
+    // don't try to load help and files if loading the help request is being cancelled
+    if (ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(projectFile)) {
+        Core::ICore::instance()->openFiles(additionalFilesToOpen);
+        Core::ICore::instance()->helpManager()->handleHelpRequest(help.toString()+QLatin1String("?view=split"));
+    }
+}
+
+void GettingStartedWelcomePage::updateTagsModel()
+{
+    m_engine->rootContext()->setContextProperty("tagsList", m_examplesModel->tags());
+    emit tagsUpdated();
+}
+
+} // namespace Internal
+} // namespace QtSupport
+
 #define GETTINGSTARTEDWELCOMEPLUGIN_H
 
 #include <utils/iwelcomepage.h>
+#include <coreplugin/icore.h>
 
-namespace Qt4ProjectManager {
+#include <QtGui/QStringListModel>
+#include <QtDeclarative/QDeclarativeItem>
+
+QT_BEGIN_NAMESPACE
+class QDeclarativeEngine;
+QT_END_NAMESPACE
+
+namespace QtSupport {
 namespace Internal {
 
+class ExamplesListModel;
 class GettingStartedWelcomePageWidget;
 
+
 class GettingStartedWelcomePage : public Utils::IWelcomePage
 {
     Q_OBJECT
 public:
     GettingStartedWelcomePage();
 
-    QWidget *page();
+    QString pageLocation() const { return Core::ICore::instance()->resourcePath() + QLatin1String("/welcomescreen/gettingstarted.qml"); }
     QString title() const { return tr("Getting Started");}
     int priority() const { return 10; }
+    void facilitateQml(QDeclarativeEngine *);
+    Q_INVOKABLE QStringList tagList() const;
+
+signals:
+    void tagsUpdated();
+
+public slots:
+    void openSplitHelp(const QUrl &help);
+    void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen, const QUrl& help);
 
 public slots:
-    void updateExamples(const QString &examplePath,
-                        const QString &demosPath,
-                        const QString &sourcePath);
+    void updateTagsModel();
 
 private:
-    GettingStartedWelcomePageWidget *m_page;
+    ExamplesListModel *m_examplesModel;
+    QDeclarativeEngine *m_engine;
 };
 
 } // namespace Internal
-} // namespace Qt4ProjectManager
+} // namespace QtSupport
 
 #endif // GETTINGSTARTEDWELCOMEPLUGIN_H
index eff34bd..25ffad2 100644 (file)
@@ -1,7 +1,7 @@
 TEMPLATE = lib
 TARGET = QtSupport
 DEFINES += QT_CREATOR QTSUPPORT_LIBRARY
-QT += network
+QT += network declarative
 include(../../qtcreatorplugin.pri)
 include(qtsupport_dependencies.pri)
 DEFINES += \
@@ -23,7 +23,9 @@ HEADERS += \
     debugginghelperbuildtask.h \
     qtsupportconstants.h \
     profilereader.h \
-    qtparser.h
+    qtparser.h \
+    gettingstartedwelcomepage.h \
+    exampleslistmodel.h
 
 SOURCES += \
     qtsupportplugin.cpp \
@@ -37,7 +39,9 @@ SOURCES += \
     qtoptionspage.cpp \
     debugginghelperbuildtask.cpp \
     profilereader.cpp \
-    qtparser.cpp
+    qtparser.cpp \
+    gettingstartedwelcomepage.cpp \
+    exampleslistmodel.cpp
 
 FORMS   +=  \
     showbuildlog.ui \
index 2c2fc40..4b7a1f4 100644 (file)
@@ -37,6 +37,8 @@
 
 #include "profilereader.h"
 
+#include "gettingstartedwelcomepage.h"
+
 #include <extensionsystem/pluginmanager.h>
 
 #include <QtCore/QtPlugin>
@@ -47,6 +49,8 @@ using namespace QtSupport::Internal;
 
 QtSupportPlugin::~QtSupportPlugin()
 {
+    removeObject(m_welcomePage);
+    delete m_welcomePage;
 }
 
 bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMessage)
@@ -60,12 +64,17 @@ bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMes
     QtVersionManager *mgr = new QtVersionManager;
     addAutoReleasedObject(mgr);
     addAutoReleasedObject(new QtOptionsPage);
+
+    m_welcomePage = new GettingStartedWelcomePage;
+    addObject(m_welcomePage);
+
     return true;
 }
 
 void QtSupportPlugin::extensionsInitialized()
 {
     QtVersionManager::instance()->extensionsInitialized();
+
 }
 
 Q_EXPORT_PLUGIN(QtSupportPlugin)
index 5423d91..a5d68c3 100644 (file)
 
 
 namespace QtSupport {
-
 namespace Internal {
 
+class GettingStartedWelcomePage;
+
 class QtSupportPlugin : public ExtensionSystem::IPlugin
 {
     Q_OBJECT
@@ -55,6 +56,8 @@ private slots:
     void testQtOutputParser_data();
     void testQtOutputParser();
 #endif
+private:
+    GettingStartedWelcomePage *m_welcomePage;
 };
 
 } // namespace Internal
index ba878e9..c05c15f 100644 (file)
 #include <QtCore/QEventLoop>
 #include <QtCore/QFile>
 #include <QtCore/QScopedPointer>
-#include <QtNetwork/QNetworkAccessManager>
 #include <QtNetwork/QNetworkRequest>
 #include <QtNetwork/QNetworkReply>
 
+#include <coreplugin/networkaccessmanager.h>
+
 using namespace TextEditor;
 using namespace Internal;
 
@@ -51,7 +52,7 @@ DefinitionDownloader::DefinitionDownloader(const QUrl &url, const QString &local
 
 void DefinitionDownloader::run()
 {
-    QNetworkAccessManager manager;
+    Core::NetworkAccessManager manager;
 
     int currentAttempt = 0;
     const int maxAttempts = 5;
index 9de8fda..d157aa6 100644 (file)
@@ -44,7 +44,8 @@
 #include <QtCore/QList>
 #include <QtCore/QSharedPointer>
 #include <QtCore/QFutureWatcher>
-#include <QtNetwork/QNetworkAccessManager>
+
+#include <coreplugin/networkaccessmanager.h>
 
 QT_BEGIN_NAMESPACE
 class QFileInfo;
@@ -114,7 +115,7 @@ private:
     QSet<QString> m_isBuilding;
 
     QList<DefinitionDownloader *> m_downloaders;
-    QNetworkAccessManager m_networkManager;
+    Core::NetworkAccessManager m_networkManager;
 
     QFutureWatcher<void> m_downloadWatcher;
     QFutureWatcher<Core::MimeType> m_mimeTypeWatcher;
index c94a236..7c5af61 100644 (file)
@@ -36,6 +36,7 @@
 #include "welcome_global.h"
 
 #include <utils/iwelcomepage.h>
+#include <coreplugin/icore.h>
 
 namespace Welcome {
 namespace Internal {
@@ -48,6 +49,7 @@ class CommunityWelcomePage : public Utils::IWelcomePage
 public:
     CommunityWelcomePage();
 
+    QString pageLocation() const { return Core::ICore::instance()->resourcePath() + QLatin1String("/welcomescreen/newssupport.qml"); }
     QWidget *page();
     QString title() const { return tr("News && Support"); }
     int priority() const { return 30; }
diff --git a/src/plugins/welcome/communitywelcomepagewidget.ui b/src/plugins/welcome/communitywelcomepagewidget.ui
deleted file mode 100644 (file)
index 8bb145d..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Welcome::Internal::CommunityWelcomePageWidget</class>
- <widget class="QWidget" name="Welcome::Internal::CommunityWelcomePageWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>667</width>
-    <height>352</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QHBoxLayout" name="horizontalLayout_2">
-   <property name="leftMargin">
-    <number>0</number>
-   </property>
-   <property name="topMargin">
-    <number>0</number>
-   </property>
-   <property name="rightMargin">
-    <number>0</number>
-   </property>
-   <property name="bottomMargin">
-    <number>2</number>
-   </property>
-   <item>
-    <widget class="QFrame" name="contentframe">
-     <property name="styleSheet">
-      <string notr="true">#contentframe{
-   border: none 0px;
-   border-bottom: 1px solid #c9c9c9;
-   margin: 0px;
-}</string>
-     </property>
-     <property name="frameShape">
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Raised</enum>
-     </property>
-     <layout class="QHBoxLayout" name="horizontalLayout">
-      <item>
-       <widget class="QFrame" name="labsFrame">
-        <property name="frameShape">
-         <enum>QFrame::NoFrame</enum>
-        </property>
-        <property name="frameShadow">
-         <enum>QFrame::Plain</enum>
-        </property>
-        <layout class="QVBoxLayout" name="verticalLayout_2">
-         <item>
-          <widget class="Utils::WelcomeModeLabel" name="labsTitleLabel">
-           <property name="text">
-            <string>News From the Qt Labs</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="Utils::WelcomeModeTreeWidget" name="newsTreeWidget" native="true"/>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item>
-       <widget class="QFrame" name="sitesFrame">
-        <property name="frameShape">
-         <enum>QFrame::NoFrame</enum>
-        </property>
-        <property name="frameShadow">
-         <enum>QFrame::Plain</enum>
-        </property>
-        <layout class="QVBoxLayout" name="verticalLayout">
-         <item>
-          <widget class="Utils::WelcomeModeLabel" name="supportSitesTitleLabel">
-           <property name="text">
-            <string>Qt Support Sites</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="Utils::WelcomeModeTreeWidget" name="supportSitesTreeWidget" native="true"/>
-         </item>
-         <item>
-          <widget class="Utils::WelcomeModeLabel" name="miscSitesTitleLabel">
-           <property name="text">
-            <string>Qt Links</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="Utils::WelcomeModeTreeWidget" name="miscSitesTreeWidget" native="true"/>
-         </item>
-         <item>
-          <spacer name="verticalSpacer">
-           <property name="orientation">
-            <enum>Qt::Vertical</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>40</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>Utils::WelcomeModeTreeWidget</class>
-   <extends>QWidget</extends>
-   <header location="global">utils/welcomemodetreewidget.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>Utils::WelcomeModeLabel</class>
-   <extends>QLabel</extends>
-   <header location="global">utils/welcomemodetreewidget.h</header>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/welcome/images/background_center_frame_v1.png b/src/plugins/welcome/images/background_center_frame_v1.png
new file mode 100644 (file)
index 0000000..e777801
Binary files /dev/null and b/src/plugins/welcome/images/background_center_frame_v1.png differ
diff --git a/src/plugins/welcome/images/background_center_frame_v2.png b/src/plugins/welcome/images/background_center_frame_v2.png
new file mode 100644 (file)
index 0000000..c2de676
Binary files /dev/null and b/src/plugins/welcome/images/background_center_frame_v2.png differ
diff --git a/src/plugins/welcome/images/tab_active.png b/src/plugins/welcome/images/tab_active.png
new file mode 100644 (file)
index 0000000..7bed3d9
Binary files /dev/null and b/src/plugins/welcome/images/tab_active.png differ
diff --git a/src/plugins/welcome/images/tab_hover.png b/src/plugins/welcome/images/tab_hover.png
new file mode 100644 (file)
index 0000000..d11cdd7
Binary files /dev/null and b/src/plugins/welcome/images/tab_hover.png differ
diff --git a/src/plugins/welcome/images/tab_inactive.png b/src/plugins/welcome/images/tab_inactive.png
new file mode 100644 (file)
index 0000000..04e804c
Binary files /dev/null and b/src/plugins/welcome/images/tab_inactive.png differ
index 19a6d87..63ca25a 100644 (file)
@@ -1,21 +1,14 @@
 TEMPLATE = lib
 TARGET = Welcome
-QT += network
+QT += network declarative
 
 include(../../qtcreatorplugin.pri)
 include(welcome_dependencies.pri)
 
 HEADERS += welcomeplugin.h \
-    communitywelcomepagewidget.h \
-    communitywelcomepage.h \
     welcome_global.h
 
-SOURCES += welcomeplugin.cpp \
-    communitywelcomepagewidget.cpp \
-    communitywelcomepage.cpp
-
-FORMS += welcomemode.ui \
-    communitywelcomepagewidget.ui
+SOURCES += welcomeplugin.cpp
 
 RESOURCES += welcome.qrc
 
index 0009b02..3c1c211 100644 (file)
         <file>images/arrow-left.png</file>
         <file>images/arrow-right.png</file>
         <file>images/welcomebg.png</file>
+        <file>images/tab_active.png</file>
+        <file>images/tab_inactive.png</file>
+        <file>images/background_center_frame_v1.png</file>
+        <file>images/background_center_frame_v2.png</file>
+        <file>images/tab_hover.png</file>
     </qresource>
 </RCC>
index 7f369f6..301ba69 100644 (file)
@@ -1,2 +1,3 @@
+include(../../plugins/projectexplorer/projectexplorer.pri)
 include(../../plugins/coreplugin/coreplugin.pri)
 include(../../libs/utils/utils.pri)
diff --git a/src/plugins/welcome/welcomemode.ui b/src/plugins/welcome/welcomemode.ui
deleted file mode 100644 (file)
index c8f6dbf..0000000
+++ /dev/null
@@ -1,470 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Welcome::WelcomeMode</class>
- <widget class="QWidget" name="Welcome::WelcomeMode">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>864</width>
-    <height>690</height>
-   </rect>
-  </property>
-  <property name="styleSheet">
-   <string notr="true">#Welcome--WelcomePage {
-background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(247, 247, 247, 255), stop:1 rgba(215, 215, 215, 255));
-}
-
-QToolButton, QPushButton, QComboBox {
-    border-image: url(:/welcome/images/btn_26.png) 4;
-    border-width: 4;
-    padding: 0px 6px;
-    font-size: 12px;
-}
-
-QToolButton, QPushButton, QComboBox, QLabel {
-    color: black;
-}
-
- QComboBox QAbstractItemView {
-    background-color:white;
-}
-
- QComboBox::down-arrow {
-     image: url(:/welcome/images/combobox_arrow.png);
- }
-QComboBox:drop-down
-{
-     subcontrol-origin: padding;
-     subcontrol-position: top right;
-     border-left-style: none; 
-     border-top-right-radius: 1px;
-     border-bottom-right-radius: 1px;
-}
-
-QToolButton:hover, QPushButton:hover, QComboBox:hover {
-    border-image: url(:/welcome/images/btn_26_hover.png) 4;
-}
-
-QToolButton:disabled, QPushButton:disabled, QComboBox::disabled {
-       color:gray;
-}
-
-QToolButton:pressed, QPushButton:pressed{
-    border-image: url(:/welcome/images/btn_26_pressed.png) 4;
-}
-
- QPushButton::menu-indicator{
-    subcontrol-origin: margin;
-       subcontrol-position: center right;
-       right: 4px;
- }
-
- QPushButton{
-       outline: none;
-       margin: 2
- }
-</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout_4">
-   <property name="spacing">
-    <number>0</number>
-   </property>
-   <property name="margin">
-    <number>0</number>
-   </property>
-   <item>
-    <widget class="QWidget" name="gradientWidget" native="true">
-     <layout class="QGridLayout" name="gridLayout">
-      <property name="leftMargin">
-       <number>0</number>
-      </property>
-      <property name="topMargin">
-       <number>4</number>
-      </property>
-      <property name="rightMargin">
-       <number>0</number>
-      </property>
-      <property name="bottomMargin">
-       <number>0</number>
-      </property>
-      <property name="spacing">
-       <number>0</number>
-      </property>
-      <item row="1" column="0">
-       <widget class="QFrame" name="mainFrame">
-        <property name="minimumSize">
-         <size>
-          <width>700</width>
-          <height>550</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>750</width>
-          <height>550</height>
-         </size>
-        </property>
-        <property name="styleSheet">
-         <string notr="true">#mainFrame {
-    border-image: url(:/welcome/images/background_center_frame.png);
-    border-width: 2;
-       padding:-1;
-    padding-bottom:20  ;
-}
-
-#contentframe{
-   border: none 0px;
-   border-bottom: 1px solid #c9c9c9;
-   background: #ffffff;
-   margin: 0px;
-}</string>
-        </property>
-        <property name="frameShape">
-         <enum>QFrame::StyledPanel</enum>
-        </property>
-        <property name="frameShadow">
-         <enum>QFrame::Raised</enum>
-        </property>
-        <layout class="QVBoxLayout" name="verticalLayout">
-         <property name="spacing">
-          <number>0</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>9</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QFrame" name="headerFrame">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>649</width>
-             <height>50</height>
-            </size>
-           </property>
-           <property name="maximumSize">
-            <size>
-             <width>649</width>
-             <height>50</height>
-            </size>
-           </property>
-           <property name="styleSheet">
-            <string>#headerFrame {
-    border-image: url(:/welcome/images/center_frame_header.png) 0;
-    border-width: 0;
-}
-</string>
-           </property>
-           <property name="frameShape">
-            <enum>QFrame::StyledPanel</enum>
-           </property>
-           <property name="frameShadow">
-            <enum>QFrame::Raised</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QFrame" name="navFrame">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>0</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="font">
-            <font>
-             <weight>50</weight>
-             <bold>false</bold>
-            </font>
-           </property>
-           <property name="cursor">
-            <cursorShape>PointingHandCursor</cursorShape>
-           </property>
-           <property name="autoFillBackground">
-            <bool>false</bool>
-           </property>
-           <property name="styleSheet">
-            <string notr="true">QToolButton {
-       border-image:none;
-       background-color: qlineargradient(x1: 0, y1: 0, x2: 0.0, y2: 1.0,
-       stop: 0 #838383,
-       stop: 0.4 #707070,
-       stop: 0.401 #636363,
-       stop: 1 #4a4a4a);
-       border: 0px solid black;
-       border-top: 1px solid #303030;
-       border-bottom: 1px solid #202020;
-       color: white;
-       height:20px;
-}
-
-QToolButton:hover {
-       border-image:none;
-       background-color: qlineargradient(x1: 0, y1: 0, x2: 0.0, y2: 1.0,
-       stop: 0 #909090,
-       stop: 0.4 #808080,
-       stop: 0.401 #707070,
-       stop: 1 #555555);
-}
-
-QToolButton:checked, QToolButton:checked:pressed {
-       border-image:none;
-       background-color: qlineargradient(x1: 0, y1: 0, x2: 0.0, y2: 1.0,
-       stop: 0 #ffffff,
-       stop: 0.4 #eeeeee,
-       stop: 0.401 #e2e2e2,
-       stop: 1 #dddddd);
-       color: black;
-       border-top: 1px solid #606060;
-       border-bottom: 1px solid #404040;
-}
-
-QToolButton:pressed {
-       border-image:none;
-       background-color: qlineargradient(x1: 0, y1: 0, x2: 0.0, y2: 1.0,
-       stop: 0 #383838,
-       stop: 0.2 #404040,
-       stop: 0.201 #484848,
-       stop: 1 #505050);
-}
-
-
-</string>
-           </property>
-           <property name="frameShape">
-            <enum>QFrame::NoFrame</enum>
-           </property>
-           <property name="frameShadow">
-            <enum>QFrame::Plain</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QStackedWidget" name="stackedWidget">
-           <property name="currentIndex">
-            <number>-1</number>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <layout class="QHBoxLayout" name="horizontalLayout">
-           <property name="leftMargin">
-            <number>8</number>
-           </property>
-           <property name="topMargin">
-            <number>1</number>
-           </property>
-           <property name="rightMargin">
-            <number>13</number>
-           </property>
-           <property name="bottomMargin">
-            <number>10</number>
-           </property>
-           <item>
-            <widget class="QPushButton" name="feedbackButton">
-             <property name="focusPolicy">
-              <enum>Qt::TabFocus</enum>
-             </property>
-             <property name="styleSheet">
-              <string notr="true">height:19px;</string>
-             </property>
-             <property name="text">
-              <string>Feedback</string>
-             </property>
-             <property name="icon">
-              <iconset resource="welcome.qrc">
-               <normaloff>:/welcome/images/feedback_arrow.png</normaloff>:/welcome/images/feedback_arrow.png</iconset>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <spacer name="horizontalSpacer_6">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeType">
-              <enum>QSizePolicy::Fixed</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>6</width>
-               <height>0</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item>
-            <widget class="QLabel" name="helpUsLabel">
-             <property name="palette">
-              <palette>
-               <active>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </active>
-               <inactive>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </inactive>
-               <disabled>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </disabled>
-              </palette>
-             </property>
-             <property name="text">
-              <string>Help us make Qt Creator even better</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <spacer name="horizontalSpacer_5">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>40</width>
-               <height>20</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-          </layout>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <spacer name="bottomVerticalSpacer">
-        <property name="orientation">
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeType">
-         <enum>QSizePolicy::Expanding</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>0</width>
-          <height>0</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item row="0" column="0">
-       <spacer name="verticalSpacer">
-        <property name="orientation">
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>20</width>
-          <height>40</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-     </layout>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources>
-  <include location="welcome.qrc"/>
- </resources>
- <connections/>
-</ui>
index d028e35..344eb5b 100644 (file)
 
 #include "welcomeplugin.h"
 
-#include "communitywelcomepage.h"
-#include "ui_welcomemode.h"
-
 #include <extensionsystem/pluginmanager.h>
 
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/icore.h>
 #include <coreplugin/imode.h>
 #include <coreplugin/modemanager.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/networkaccessmanager.h>
+#include <coreplugin/dialogs/iwizard.h>
+
+#include <projectexplorer/projectexplorer.h>
 
 #include <utils/styledbar.h>
 #include <utils/welcomemodetreewidget.h>
 
 #include <QtGui/QScrollArea>
 #include <QtGui/QDesktopServices>
-#include <QtGui/QToolButton>
 #include <QtGui/QPainter>
+#include <QtGui/QHBoxLayout>
 
 #include <QtCore/QSettings>
 #include <QtCore/QDebug>
 #include <QtCore/QUrl>
 #include <QtCore/QtPlugin>
 
+#include <QtDeclarative/QDeclarativeView>
+#include <QtDeclarative/QDeclarativeContext>
+#include <QtDeclarative/QDeclarativeEngine>
+#include <QtDeclarative/QDeclarativeNetworkAccessManagerFactory>
+
 enum { debug = 0 };
 
 using namespace ExtensionSystem;
 
+static const char currentPageSettingsKeyC[] = "WelcomeTab";
+
 namespace Welcome {
 namespace Internal {
 
-// Helper class introduced to cache the scaled background image
-// so we avoid re-scaling for every repaint.
-class ImageWidget : public QWidget
+class NetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory
 {
 public:
-    explicit ImageWidget(QWidget *parent)
-        : QWidget(parent),
-          m_bg(":/welcome/images/welcomebg.png")
-    {}
+    NetworkAccessManagerFactory(): QDeclarativeNetworkAccessManagerFactory() {}
+    QNetworkAccessManager* create(QObject *parent) { return new Core::NetworkAccessManager(parent); }
+};
 
-    void paintEvent(QPaintEvent *e)
-    {
-        if (!m_bg.isNull()) {
-            QPainter painter(this);
-            if (m_stretch.size() != size())
-                m_stretch = QPixmap::fromImage(m_bg.scaled(size(),
-                    Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
-            if (!m_stretch.size().isEmpty())
-                painter.drawPixmap(rect(), m_stretch);
-        }
-        QWidget::paintEvent(e);
-    }
 
-private:
-    QImage m_bg;
-    QPixmap m_stretch;
+struct WelcomeModePrivate
+{
+
 };
 
 class WelcomeMode : public Core::IMode
 {
     Q_OBJECT
-
+    Q_PROPERTY(int activePlugin READ activePlugin WRITE setActivePlugin NOTIFY activePluginChanged)
 public:
     WelcomeMode();
     ~WelcomeMode();
 
     void activated();
     void initPlugins();
+    int activePlugin() const { return m_activePlugin; }
+
+public slots:
+    void sendFeedback();
+    void newProject();
+    void openProject();
+
+    void setActivePlugin(int pos)
+    {
+        if (m_activePlugin != pos) {
+            m_activePlugin = pos;
+            emit activePluginChanged(pos);
+        }
+    }
+
+signals:
+    void activePluginChanged(int pos);
 
 private slots:
-    void slotFeedback();
     void welcomePluginAdded(QObject*);
-    void showClickedPage();
+    void modeChanged(Core::IMode*);
 
 private:
-    void addPageToolButton(Utils::IWelcomePage *plugin, int position = -1);
-
-    typedef QMap<QToolButton *, QWidget *> ToolButtonWidgetMap;
-
-    QScrollArea m_scrollArea;
-    QWidget m_outerWidget;
-    ImageWidget *m_welcomePage;
-    ToolButtonWidgetMap buttonMap;
-    QHBoxLayout *buttonLayout;
-    Ui::WelcomeMode ui;
+    QScrollArea *m_scrollArea;
+    QDeclarativeView *m_welcomePage;
+    QHBoxLayout * buttonLayout;
+    QList<QObject*> m_pluginList;
+    int m_activePlugin;
 };
 
-static const char currentPageSettingsKeyC[] = "General/WelcomeTab";
-
 // ---  WelcomeMode
-WelcomeMode::WelcomeMode()
+WelcomeMode::WelcomeMode() :
+    m_activePlugin(0)
 {
     setDisplayName(tr("Welcome"));
     setIcon(QIcon(QLatin1String(Core::Constants::ICON_QTLOGO_32)));
@@ -132,118 +136,111 @@ WelcomeMode::WelcomeMode()
     setType(QLatin1String(Core::Constants::MODE_WELCOME_TYPE));
     setContextHelpId(QLatin1String("Qt Creator Manual"));
     setContext(Core::Context(Core::Constants::C_WELCOME_MODE));
-    setWidget(&m_scrollArea);
-
-    QVBoxLayout *l = new QVBoxLayout(&m_outerWidget);
-    l->setMargin(0);
-    l->setSpacing(0);
-    l->addWidget(new Utils::StyledBar(&m_outerWidget));
-    m_welcomePage = new ImageWidget(&m_outerWidget);
-    ui.setupUi(m_welcomePage);
-    ui.helpUsLabel->setAttribute(Qt::WA_LayoutUsesWidgetRect);
-    ui.feedbackButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
-    l->addWidget(m_welcomePage);
-
-    m_scrollArea.setFrameStyle(QFrame::NoFrame);
-    m_scrollArea.setWidget(&m_outerWidget);
-    m_scrollArea.setWidgetResizable(true);
+
+    m_welcomePage = new QDeclarativeView;
+    m_welcomePage->setResizeMode(QDeclarativeView::SizeRootObjectToView);
+
+    m_scrollArea = new QScrollArea;
+    m_scrollArea->setFrameStyle(QFrame::NoFrame|QFrame::Plain);
+    m_scrollArea->setWidget(m_welcomePage);
+    m_scrollArea->setWidgetResizable(true);
 
     PluginManager *pluginManager = PluginManager::instance();
     connect(pluginManager, SIGNAL(objectAdded(QObject*)), SLOT(welcomePluginAdded(QObject*)));
 
-    connect(ui.feedbackButton, SIGNAL(clicked()), SLOT(slotFeedback()));
+    Core::ModeManager *modeManager = Core::ICore::instance()->modeManager();
+    connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*)), SLOT(modeChanged(Core::IMode*)));
+
+    setWidget(m_scrollArea);
 }
 
 WelcomeMode::~WelcomeMode()
 {
     QSettings *settings = Core::ICore::instance()->settings();
-    settings->setValue(QLatin1String(currentPageSettingsKeyC), ui.stackedWidget->currentIndex());
+    settings->setValue(QLatin1String(currentPageSettingsKeyC), activePlugin());
+    delete m_scrollArea;
 }
 
-bool sortFunction(Utils::IWelcomePage *a, Utils::IWelcomePage *b)
+bool sortFunction(Utils::IWelcomePage * a, Utils::IWelcomePage *b)
 {
     return a->priority() < b->priority();
 }
 
-// Create a QToolButton for a page
-void WelcomeMode::addPageToolButton(Utils::IWelcomePage *plugin, int position)
-{
-    QToolButton *btn = new QToolButton;
-    btn->setCheckable(true);
-    btn->setText(plugin->title());
-    btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
-    btn->setAutoExclusive(true);
-    connect(btn, SIGNAL(clicked()), SLOT(showClickedPage()));
-    buttonMap.insert(btn, plugin->page());
-    if (position >= 0)
-        buttonLayout->insertWidget(position, btn);
-    else
-        buttonLayout->addWidget(btn);
-}
-
 void WelcomeMode::initPlugins()
 {
-    buttonLayout = new QHBoxLayout(ui.navFrame);
-    buttonLayout->setMargin(0);
-    buttonLayout->setSpacing(0);
+    QSettings *settings = Core::ICore::instance()->settings();
+    setActivePlugin(settings->value(QLatin1String(currentPageSettingsKeyC)).toInt());
+
+    QDeclarativeContext *ctx = m_welcomePage->rootContext();
+    ctx->setContextProperty("welcomeMode", this);
+
     QList<Utils::IWelcomePage*> plugins = PluginManager::instance()->getObjects<Utils::IWelcomePage>();
     qSort(plugins.begin(), plugins.end(), &sortFunction);
+
+    QDeclarativeEngine *engine = m_welcomePage->engine();
+    engine->setNetworkAccessManagerFactory(new NetworkAccessManagerFactory);
     foreach (Utils::IWelcomePage *plugin, plugins) {
-        ui.stackedWidget->addWidget(plugin->page());
-        addPageToolButton(plugin);
-        if (debug)
-            qDebug() << "WelcomeMode::initPlugins" << plugin->title();
+        plugin->facilitateQml(engine);
+        m_pluginList.append(plugin);
     }
-    QSettings *settings = Core::ICore::instance()->settings();
-    const int tabId = settings->value(QLatin1String(currentPageSettingsKeyC), 0).toInt();
 
-    const int pluginCount = ui.stackedWidget->count();
-    if (tabId >= 0 && tabId < pluginCount) {
-        ui.stackedWidget->setCurrentIndex(tabId);
-        if (QToolButton *btn = buttonMap.key(ui.stackedWidget->currentWidget()))
-            btn->setChecked(true);
-    }
+    ctx->setContextProperty("pagesModel", QVariant::fromValue(m_pluginList));
+
+    // finally, load the root page
+    m_welcomePage->setSource(
+            QUrl::fromLocalFile(Core::ICore::instance()->resourcePath() + "/welcomescreen/welcomescreen.qml"));
 }
 
 void WelcomeMode::welcomePluginAdded(QObject *obj)
 {
-    Utils::IWelcomePage *plugin = qobject_cast<Utils::IWelcomePage*>(obj);
-    if (!plugin)
-        return;
-
-    int insertPos = 0;
-    QList<Utils::IWelcomePage *> pages
-        = PluginManager::instance()->getObjects<Utils::IWelcomePage>();
-    foreach (Utils::IWelcomePage *p, pages) {
-        if (plugin->priority() >= p->priority())
-            break;
-        insertPos++;
+    if (Utils::IWelcomePage *plugin = qobject_cast<Utils::IWelcomePage*>(obj)) {
+        int insertPos = 0;
+        foreach (Utils::IWelcomePage* p, PluginManager::instance()->getObjects<Utils::IWelcomePage>()) {
+            if (plugin->priority() < p->priority())
+                insertPos++;
+            else
+                break;
+        }
+        m_pluginList.insert(insertPos, plugin);
+        // update model through reset
+        QDeclarativeContext *ctx = m_welcomePage->rootContext();
+        ctx->setContextProperty("pagesModel", QVariant::fromValue(m_pluginList));
     }
-    ui.stackedWidget->insertWidget(insertPos, plugin->page());
-    addPageToolButton(plugin, insertPos);
-    if (debug)
-        qDebug() << "welcomePluginAdded" << plugin->title() << "at" << insertPos
-                 << " of " << buttonMap.size();
 }
 
-void WelcomeMode::showClickedPage()
+void WelcomeMode::sendFeedback()
+{
+    QDesktopServices::openUrl(QUrl(QLatin1String(
+        "http://qt.nokia.com/forms/feedback-forms/qt-creator-user-feedback/view")));
+}
+
+void WelcomeMode::newProject()
 {
-    QToolButton *btn = qobject_cast<QToolButton*>(sender());
-    const ToolButtonWidgetMap::const_iterator it = buttonMap.constFind(btn);
-    if (it != buttonMap.constEnd())
-        ui.stackedWidget->setCurrentWidget(it.value());
+    Core::ICore::instance()->showNewItemDialog(tr("New Project"),
+                                               Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard));
 }
 
-void WelcomeMode::slotFeedback()
+void WelcomeMode::openProject()
 {
-    QDesktopServices::openUrl(QUrl(QLatin1String(
-        "http://qt.nokia.com/forms/feedback-forms/qt-creator-user-feedback/view")));
+    ProjectExplorer::ProjectExplorerPlugin::instance()->openOpenProjectDialog();
 }
 
+void WelcomeMode::modeChanged(Core::IMode *mode)
+{
+    Q_UNUSED(mode)
 
-//
+// Eike doesn't like this, but I do...
 
+//    ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
+//    Core::ModeManager *modeManager = Core::ICore::instance()->modeManager();
+//    Core::EditorManager *editorManager = Core::ICore::instance()->editorManager();
+//    if (mode->id() == id() && (!projectExplorer->currentProject() && editorManager->openedEditors().isEmpty()))
+//        modeManager->setModeBarHidden(true);
+//    else
+//        modeManager->setModeBarHidden(false);
+}
 
+//
 
 WelcomePlugin::WelcomePlugin()
   : m_welcomeMode(0)
@@ -258,8 +255,6 @@ WelcomePlugin::WelcomePlugin()
 */
 bool WelcomePlugin::initialize(const QStringList & /* arguments */, QString * /* error_message */)
 {
-    addAutoReleasedObject(new Internal::CommunityWelcomePage);
-
     m_welcomeMode = new WelcomeMode;
     addAutoReleasedObject(m_welcomeMode);
 
@@ -283,8 +278,8 @@ void WelcomePlugin::extensionsInitialized()
     Core::ModeManager::instance()->activateMode(m_welcomeMode->id());
 }
 
-} // namespace Welcome
 } // namespace Internal
+} // namespace Welcome
 
 
 Q_EXPORT_PLUGIN(Welcome::Internal::WelcomePlugin)
diff --git a/src/tools/examplesscanner/examplesscanner.pro b/src/tools/examplesscanner/examplesscanner.pro
new file mode 100644 (file)
index 0000000..531a4aa
--- /dev/null
@@ -0,0 +1,9 @@
+QT += declarative xml network
+CONFIG += help
+
+SOURCES += \
+    main.cpp \
+    helpextractor.cpp
+
+HEADERS += \
+    helpextractor.h
diff --git a/src/tools/examplesscanner/helpextractor.cpp b/src/tools/examplesscanner/helpextractor.cpp
new file mode 100644 (file)
index 0000000..7fad855
--- /dev/null
@@ -0,0 +1,372 @@
+#include "helpextractor.h"
+
+#include <QtGui>
+#include <QDebug>
+
+HelpExtractor::HelpExtractor()
+{
+    initHelpEngine();
+}
+
+void HelpExtractor::initHelpEngine()
+{
+    helpRootUrl = QString("qthelp://com.trolltech.qt/qdoc/");
+    //        .arg(QT_VERSION >> 16).arg((QT_VERSION >> 8) & 0xFF)
+    //        .arg(QT_VERSION & 0xFF);
+
+    // Store help collection file in cache dir of assistant
+    QString cacheDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation)
+            + QLatin1String("/Trolltech/Assistant/");
+    QString helpDataFile = QString(QLatin1String("qtdemo_%1.qhc")).arg(QLatin1String(QT_VERSION_STR));
+
+    QDir dir;
+    if (!dir.exists(cacheDir))
+        dir.mkpath(cacheDir);
+
+    // Create help engine (and new
+    // helpDataFile if it does not exist):
+    helpEngine = new QHelpEngineCore(cacheDir + helpDataFile);
+    helpEngine->setupData();
+
+    QString qtDocRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/qch");
+    qtDocRoot = QDir(qtDocRoot).absolutePath();
+
+    QStringList qchFiles;
+    qchFiles << QLatin1String("/qt.qch")
+             << QLatin1String("/designer.qch")
+             << QLatin1String("/linguist.qch");
+
+    QString oldDir = helpEngine->customValue(QLatin1String("docDir"), QString()).toString();
+    if (oldDir != qtDocRoot) {
+        foreach (const QString &qchFile, qchFiles)
+            helpEngine->unregisterDocumentation(QHelpEngineCore::namespaceName(qtDocRoot + qchFile));
+    }
+
+    // If the data that the engine will work
+    // on is not yet registered, do it now:
+    foreach (const QString &qchFile, qchFiles)
+        helpEngine->registerDocumentation(qtDocRoot + qchFile);
+
+    helpEngine->setCustomValue(QLatin1String("docDir"), qtDocRoot);
+}
+
+void HelpExtractor::readXmlDocument()
+{
+    contentsDoc = new QDomDocument();
+    QString errorStr;
+    int errorLine;
+    int errorColumn;
+
+    QString qtDemoPath = QLibraryInfo::location(QLibraryInfo::DemosPath) + QLatin1String("/qtdemo");
+    QFile file(qtDemoPath + "/xml/examples.xml");
+    bool statusOK = contentsDoc->setContent(&file, true, &errorStr, &errorLine, &errorColumn);
+    if (!statusOK) {
+        qDebug() << QString::fromLatin1("DOM Parser: Could not read or find the contents document. Error at line %1, column %2:\n%3")
+                    .arg(errorLine).arg(errorColumn).arg(errorStr);
+        exit(-1);
+    }
+    //convertToSql(contentsDoc->documentElement());
+    convertToAggregatableXml(contentsDoc->documentElement());
+}
+
+
+void HelpExtractor::convertToAggregatableXml(const QDomElement &documentElement)
+{
+    QDomDocument outDocument;
+    QDomElement root = outDocument.createElement("instructionals");
+    QDomElement demos = outDocument.createElement("demos");
+    QDomElement examples = outDocument.createElement("examples");
+    QDomElement tutorials = outDocument.createElement("tutorials");
+    root.setAttribute("module", "Qt");
+    root.appendChild(demos);
+    root.appendChild(examples);
+    root.appendChild(tutorials);
+    outDocument.appendChild(root);
+
+    QDomNode currentNode = documentElement.firstChild();
+    QDomElement step, steps, instructional;
+    int id = 0;
+    while (!currentNode.isNull()){
+        //qDebug() << '\t' << label;
+        QDomNode sub = currentNode.firstChild();
+        while (!sub.isNull()) {
+            QDomElement element = sub.toElement();
+            readInfoAboutExample(element);
+            QString exampleName = element.attribute("name");
+            StringHash exampleInfo = info[exampleName];
+
+            // type = category - last char
+            QString category = exampleInfo["category"];
+            QString categoryName = sub.parentNode().toElement().attribute("name");
+            QString type = category;
+            type.chop(1);
+
+            QString dirName = exampleInfo["dirname"];
+
+            if (category != "tutorial" || (category == "tutorial" && category != lastCategory)) {
+                instructional = outDocument.createElement(type);
+                if (category == "tutorial" && category != lastCategory)
+                    instructional.setAttribute("name", categoryName);
+                else
+                    instructional.setAttribute("name", exampleName);
+            }
+
+            QString projectPath = dirName + '/' + exampleInfo["filename"] + '/' + exampleInfo["filename"];
+
+            bool qml = (exampleInfo["qml"] == "true");
+            if (qml)
+                projectPath += ".qmlproject";
+            else
+                projectPath += ".pro";
+
+
+            if (category == "tutorials")
+            {
+                if (category != lastCategory) {
+                    steps = outDocument.createElement("steps");
+                    instructional.appendChild(steps);
+                }
+
+                step = outDocument.createElement("step");
+                step.setAttribute("projectPath", projectPath);
+                step.setAttribute("imageUrl", getImageUrl(exampleName));
+                step.setAttribute("docUrl", resolveDocUrl(exampleName));
+                steps.appendChild(step);
+            }
+
+            instructional.setAttribute("projectPath", projectPath);
+            instructional.setAttribute("imageUrl", getImageUrl(exampleName));
+            instructional.setAttribute("docUrl", resolveDocUrl(exampleName));
+            instructional.setAttribute("difficulty", "?");
+            QDomElement description = outDocument.createElement("description");
+            QString descriptionText = loadDescription(exampleName);
+            description.appendChild(outDocument.createCDATASection(descriptionText));
+            QDomElement tags = outDocument.createElement("tags");
+            // TODO
+            QStringList tagList;
+            tagList << type << exampleInfo["filename"].split('/');
+            if (dirName != ".")
+                tagList << dirName.split('/');
+            if (qml)
+                tagList << "qml" << "qt quick";
+            QRegExp ttText("<tt>(.*)</tt>");
+            ttText.setMinimal(true); // non-greedy
+            int index = 0;
+            QStringList keywords;
+            while ((index = ttText.indexIn(descriptionText, index)) != -1) {
+                keywords << descriptionText.mid(index+4, ttText.matchedLength()-9);
+                index = index + ttText.matchedLength();
+            }
+
+            // Blacklist Checking...
+            QStringList blackList;
+            blackList << "license" << "trafikanten";
+            foreach (const QString& keyword, keywords)
+                if (!keyword.isEmpty())  {
+                    bool skip = false;
+                    foreach (const QString& blackListItem, blackList)
+                        if (keyword.contains(blackListItem, Qt::CaseInsensitive)) {
+                            skip = true;
+                            break;
+                        }
+                    if (!skip)
+                        tagList << keyword.simplified().toLower();
+                }
+
+            tags.appendChild(outDocument.createTextNode(tagList.join(",")));
+            instructional.appendChild(description);
+            instructional.appendChild(tags);
+
+            if (category != "tutorials") {
+                if (category == "demos")
+                    demos.appendChild(instructional);
+                else
+                    examples.appendChild(instructional);
+            } else if (lastCategory != "tutorials")
+                tutorials.appendChild(instructional);
+
+            id++;
+            sub = sub.nextSibling();
+            lastCategory = category;
+
+        }
+        currentNode = currentNode.nextSibling();
+    }
+
+
+    QFile outFile("../../../share/qtcreator/welcomescreen/examples_fallback.xml");
+
+    QByteArray xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+    xml += outDocument.toByteArray();
+    if (!outFile.open(QIODevice::WriteOnly))
+        return;
+    outFile.write(xml);
+    //qDebug() << xml;
+    outFile.close();
+
+}
+
+QString HelpExtractor::loadDescription(const QString &name)
+{
+    QByteArray ba = getHtml(name);
+    QString errorMsg;
+    int errorLine, errorColumn;
+
+    QDomDocument exampleDoc;
+    if (ba.isEmpty()) {
+        qDebug() << "No documentation found for" << name << "Is the documentation built?";
+    } else if (!exampleDoc.setContent(ba, false, &errorMsg, &errorLine, &errorColumn)) {
+        qDebug() << "Error loading documentation for " << name << ": " << errorMsg << errorLine << errorColumn;
+    }
+
+    QDomNodeList paragraphs = exampleDoc.elementsByTagName("p");
+    if (paragraphs.length() < 1)
+        qDebug() << "- ExampleContent::loadDescription(): Could not load description:"
+                 << info[name]["docfile"];
+    QString description = QLatin1String("");
+    for (int p = 0; p < int(paragraphs.length()); ++p) {
+        description = extractTextFromParagraph(paragraphs.item(p));
+        if (isSummaryOf(description, name)) {
+            break;
+        }
+    }
+    return description;
+}
+
+void HelpExtractor::readInfoAboutExample(const QDomElement &example)
+{
+    QString name = example.attribute("name");
+    if (info.contains(name))
+        qWarning() << "__WARNING: HelpExtractor::readInfoAboutExample: Demo/example with name"
+                   << name << "appears twice in the xml-file!__";
+
+    info[name]["filename"] = example.attribute("filename");
+    QString dirName = example.parentNode().toElement().attribute("dirname");
+    info[name]["dirname"] =  dirName;
+    QString category;
+    if (dirName.startsWith("tutorials"))
+        category = "tutorials";
+    else
+        category = example.parentNode().toElement().tagName();
+
+    if (category == "category")
+        category = "examples";
+
+    info[name]["category"] = category;
+    info[name]["changedirectory"] = example.attribute("changedirectory");
+    info[name]["image"] = example.attribute("image");
+    info[name]["qml"] = example.attribute("qml");
+}
+
+QString HelpExtractor::resolveDocUrl(const QString &name)
+{
+    QString dirName = info[name]["dirname"];
+    QString category = info[name]["category"];
+    QString fileName = info[name]["filename"];
+
+    if (category == "demos")
+        return helpRootUrl + "demos-" + fileName.replace("/", "-") + ".html";
+    else
+        return helpRootUrl + dirName.replace("/", "-") + "-" + fileName + ".html";
+}
+
+
+QString HelpExtractor::resolveImageUrl(const QString &name)
+{
+    return helpRootUrl + "images/" + name;
+}
+
+QByteArray HelpExtractor::getResource(const QString &name)
+{
+    return helpEngine->fileData(name);
+}
+
+QByteArray HelpExtractor::getHtml(const QString &name)
+{
+    return getResource(resolveDocUrl(name));
+}
+
+QByteArray HelpExtractor::getImage(const QString &name)
+{
+    QString imageName = this->info[name]["image"];
+    QString category = this->info[name]["category"];
+    QString fileName = this->info[name]["filename"];
+    bool qml = (this->info[name]["qml"] == QLatin1String("true"));
+    if (qml)
+        fileName = QLatin1String("qml-") + fileName.split('/').last();
+
+    if (imageName.isEmpty()){
+        if (category == "demos")
+            imageName = fileName + "-demo.png";
+        else
+            imageName = fileName + "-example.png";
+        if ((getResource(resolveImageUrl(imageName))).isEmpty())
+            imageName = fileName + ".png";
+        if ((getResource(resolveImageUrl(imageName))).isEmpty())
+            imageName = fileName + "example.png";
+    }
+    return getResource(resolveImageUrl(imageName));
+}
+
+QString HelpExtractor::getImageUrl(const QString &name)
+{
+    QString imageName = this->info[name]["image"];
+    QString category = this->info[name]["category"];
+    QString fileName = this->info[name]["filename"];
+    bool qml = (this->info[name]["qml"] == QLatin1String("true"));
+    if (qml)
+        fileName = QLatin1String("qml-") + fileName.split('/').last();
+
+    if (imageName.isEmpty()){
+        if (category == "demos")
+            imageName = fileName + "-demo.png";
+        else
+            imageName = fileName + "-example.png";
+        if ((getResource(resolveImageUrl(imageName))).isEmpty())
+            imageName = fileName + ".png";
+        if ((getResource(resolveImageUrl(imageName))).isEmpty())
+            imageName = fileName + "example.png";
+        if ((getResource(resolveImageUrl(imageName))).isEmpty())
+            return "";
+    }
+    return resolveImageUrl(imageName);
+}
+
+QString HelpExtractor::extractTextFromParagraph(const QDomNode &parentNode)
+{
+    QString description;
+    QDomNode node = parentNode.firstChild();
+
+    while (!node.isNull()) {
+        QString beginTag;
+        QString endTag;
+        if (node.isText())
+            description += node.nodeValue();
+        else if (node.hasChildNodes()) {
+            if (node.nodeName() == "b") {
+                beginTag = "<b>";
+                endTag = "</b>";
+            } else if (node.nodeName() == "a") {
+                beginTag = "<tt>";
+                endTag = "</tt>";
+            } else if (node.nodeName() == "i") {
+                beginTag = "<i>";
+                endTag = "</i>";
+            } else if (node.nodeName() == "tt") {
+                beginTag = "<tt>";
+                endTag = "</tt>";
+            }
+            description += beginTag + extractTextFromParagraph(node) + endTag;
+        }
+        node = node.nextSibling();
+    }
+
+    return description;
+}
+
+bool HelpExtractor::isSummaryOf(const QString &text, const QString &example)
+{
+    return (!text.contains("[") &&
+            text.indexOf(QRegExp(QString("(In )?((The|This) )?(%1 )?.*(tutorial|example|demo|application)").arg(example),
+                                 Qt::CaseInsensitive)) != -1);
+}
diff --git a/src/tools/examplesscanner/helpextractor.h b/src/tools/examplesscanner/helpextractor.h
new file mode 100644 (file)
index 0000000..4210a66
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef HELPEXTRACTOR_H
+#define HELPEXTRACTOR_H
+
+#include <QtCore>
+#include <QtXml>
+#include <QtHelp>
+
+typedef QHash<QString, QString> StringHash;
+typedef QHash<QString, StringHash> HashHash;
+
+class HelpExtractor
+{
+public:
+    HelpExtractor();
+    void readXmlDocument();
+
+private:
+    void initHelpEngine();
+    void convertToAggregatableXml(const QDomElement &documentElement);
+    QByteArray getResource(const QString &name);
+    QByteArray getHtml(const QString &name);
+    QByteArray getImage(const QString &name);
+    QString getImageUrl(const QString &name);
+    QString resolveDocUrl(const QString &name);
+    QString resolveImageUrl(const QString &name);
+    QString loadDescription(const QString &name);
+    void readInfoAboutExample(const QDomElement &example);
+    QString extractTextFromParagraph(const QDomNode &parentNode);
+    bool isSummaryOf(const QString &text, const QString &example);
+
+    HashHash info;
+    QHelpEngineCore *helpEngine;
+    QDomDocument *contentsDoc;
+    QString helpRootUrl;
+    QDir docDir;
+    QDir imgDir;
+    QString lastCategory;
+
+};
+
+#endif // HELPEXTRACTOR_H
diff --git a/src/tools/examplesscanner/main.cpp b/src/tools/examplesscanner/main.cpp
new file mode 100644 (file)
index 0000000..5c47a97
--- /dev/null
@@ -0,0 +1,9 @@
+#include <QtCore>
+
+#include "helpextractor.h"
+
+int main(int argc, char *argv[])
+{
+    HelpExtractor extractor;
+    extractor.readXmlDocument();
+}